Copepod Collection
Copepods were collected at approximately weekly intervals from Lake
Champlain (Burlington Fishing Pier). Plankton was collected from the top
3 meters using a 250 um mesh net.
# Lake Champlain near Burlington, VT
siteNumber = "04294500"
ChamplainInfo = readNWISsite(siteNumber)
parameterCd = "00010"
startDate = "2023-01-01"
endDate = ""
#statCd = c("00001", "00002","00003", "00011") # 1 - max, 2 - min, 3 = mean
# Constructs the URL for the data wanted then downloads the data
url = constructNWISURL(siteNumbers = siteNumber, parameterCd = parameterCd,
startDate = startDate, endDate = endDate, service = "uv")
raw_temps = importWaterML1(url, asDateTime = T) %>%
mutate("date" = as.Date(dateTime)) %>%
select(dateTime, tz_cd, date, degC = X_00010_00000)
temp_data = raw_temps %>%
select(date, "temp" = degC)
Collections began in late May 2023. Several gaps are present, but
collections have continued at roughly weekly intervals since then.
Copepods from 46 collections were used to make a total of 1232 thermal
limit measurements. Over this time period, collection temperatures
ranged from 2.5 to 26.5°C.
There is substantial variation in thermal limits across the species
collected. There is also some degree of variation within the species,
with thermal limits increasing slightly during the summer.
## Daily values for the period examined by dataset
collection_conditions = temp_data %>%
ungroup() %>%
group_by(date) %>%
summarise(mean_temp = mean(temp),
med_temp = median(temp),
var_temp = var(temp),
min_temp = min(temp),
max_temp = max(temp)) %>%
mutate("range_temp" = max_temp - min_temp,
date = as.Date(date)) %>%
ungroup() %>%
filter(date >= (min(as.Date(full_data$collection_date)) - 7))
## Mean female thermal limits for each species, grouped by collection
species_summaries = full_data %>%
#filter(sex == "female") %>%
group_by(sp_name, collection_date, collection_temp) %>%
summarise("mean_ctmax" = mean(ctmax),
"sample_size" = n(),
"ctmax_st_err" = (sd(ctmax) / sqrt(sample_size)),
"ctmax_var" = var(ctmax),
"mean_size" = mean(size),
"size_st_err" = (sd(size) / sqrt(sample_size)),
"size_var" = var(size)) %>%
ungroup() %>%
complete(sp_name, collection_date) %>%
arrange(desc(sample_size))
adult_summaries = full_data %>%
filter(sex == "female") %>%
group_by(sp_name, collection_date, collection_temp) %>%
summarise("mean_ctmax" = mean(ctmax),
"sample_size" = n(),
"ctmax_st_err" = (sd(ctmax) / sqrt(sample_size)),
"ctmax_var" = var(ctmax),
"mean_size" = mean(size),
"size_st_err" = (sd(size) / sqrt(sample_size)),
"size_var" = var(size)) %>%
ungroup() %>%
complete(sp_name, collection_date) %>%
arrange(desc(sample_size))
ggplot() +
geom_vline(data = unique(select(full_data, collection_date)),
aes(xintercept = as.Date(collection_date)),
colour = "grey90",
linewidth = 1) +
geom_line(data = collection_conditions,
aes(x = as.Date(date), y = mean_temp),
colour = "black",
linewidth = 2) +
# geom_errorbar(data = species_summaries,
# aes(x = as.Date(collection_date),
# ymin = mean_ctmax - ctmax_st_err, ymax = mean_ctmax + ctmax_st_err,
# colour = sp_name),
# position = position_dodge(width = 1),
# width = 5, linewidth = 1) +
# geom_point(data = adult_summaries,
# aes(x = as.Date(collection_date), y = mean_ctmax, colour = sp_name, size = sample_size)) +
geom_point(data = full_data,
aes(x = as.Date(collection_date), y = ctmax, colour = sp_name),
size = 2, position = position_jitter(width = 1, height = 0)) +
scale_colour_manual(values = species_cols) +
labs(x = "Date",
y = "Temperature (°C)",
colour = "Species",
size = "Sample Size") +
theme_matt() +
theme(legend.position = "right")

round_summary = full_data %>%
group_by(collection_date, collection_temp) %>%
summarise(mean_ctmax = mean(ctmax))
ggplot(data = round_summary) +
geom_hline(yintercept = 40) +
geom_point(aes(x = as_date(collection_date), y = mean_ctmax),
colour = "tomato3",
size = 5) +
geom_bar(aes(x = as_date(collection_date), y = mean_ctmax),
stat = "identity",
fill = "white",
colour = "grey30") +
geom_bar(aes(x = as_date(collection_date), y = collection_temp),
stat = "identity",
fill = "darkgoldenrod1") +
ylim(-3, 40) +
coord_polar(start = 0) +
theme_void()

ggplot() +
geom_hline(yintercept =
c(max(full_data$collection_temp),
min(full_data$collection_temp)),
colour = "grey60",
linewidth = c(2,1),
alpha = 0.5) +
geom_bar(data = unique(select(full_data, collection_date, collection_temp)),
aes(x = as_date(collection_date), y = collection_temp),
stat = "identity",
fill = "grey30") +
geom_point(data = full_data,
aes(x = as_date(collection_date), y = ctmax),
position = position_jitter(width = 0.7, height = 0),
colour = "grey30",
alpha = 0.5) +
ylim(-3, 40) +
coord_polar(start = 0) +
theme_void()

Size also varied, but primarily between rather than within
species.
ggplot() +
geom_vline(data = unique(select(full_data, collection_date)),
aes(xintercept = as.Date(collection_date)),
colour = "grey90",
linewidth = 1) +
geom_line(data = collection_conditions,
aes(x = as.Date(date), y = mean_temp),
colour = "black",
linewidth = 2) +
# geom_errorbar(data = species_summaries,
# aes(x = as.Date(collection_date),
# ymin = mean_ctmax - ctmax_st_err, ymax = mean_ctmax + ctmax_st_err,
# colour = sp_name),
# position = position_dodge(width = 1),
# width = 5, linewidth = 1) +
geom_point(data = adult_summaries,
aes(x = as.Date(collection_date), y = mean_size * 40, colour = sp_name, size = sample_size),
position = position_dodge(width = 1)) +
scale_colour_manual(values = species_cols) +
scale_y_continuous(
name = "Temperature", # Features of the first axis
sec.axis = sec_axis(~./40, name="Prosome Length (mm)"), # Add a second axis and specify its features
breaks = c(0,5,10,15,20,25,30)
) +
labs(x = "Date",
y = "Temperature (°C)",
colour = "Species") +
theme_matt() +
theme(legend.position = "right")

Shown below is CTmax and body size for the species with the most data
(Skistodiaptomus, L. minutus, L. sicilis, and
Epischura), plotted against the day of the year for each
sex/stage separately.
ctmax_feature = full_data %>%
mutate(doy = yday(collection_date)) %>%
filter(sp_name %in% c("Skistodiaptomus oregonensis", "Leptodiaptomus minutus", "Leptodiaptomus sicilis", "Epischura lacustris")) %>%
ggplot(aes(x = as.Date(collection_date), y = ctmax, colour = sp_name)) +
facet_grid(sp_name~sex) +
geom_point() +
scale_colour_manual(values = species_cols) +
labs(x = "Day of the Year",
y = "CTmax (°C)") +
theme_matt_facets() +
theme(axis.text.x = element_text(angle = 300, hjust = 0, vjust = 0.5),
legend.position = "none")
size_feature = full_data %>%
mutate(doy = yday(collection_date)) %>%
filter(sp_name %in% c("Skistodiaptomus oregonensis", "Leptodiaptomus minutus", "Leptodiaptomus sicilis", "Epischura lacustris")) %>%
ggplot(aes(x = as.Date(collection_date), y = size, colour = sp_name)) +
facet_grid(sp_name~sex) +
geom_point() +
scale_colour_manual(values = species_cols) +
labs(x = "Day of the Year",
y = "Size (mm)") +
theme_matt_facets() +
theme(axis.text.x = element_text(angle = 300, hjust = 0, vjust = 0.5),
legend.position = "none")
ggarrange(ctmax_feature, size_feature, common.legend = T, legend = "none")

adult_summaries %>%
ungroup() %>%
mutate(collection_num = as.numeric(factor(collection_date))) %>%
group_by(collection_date) %>%
arrange(collection_date) %>%
select(sp_name, collection_date, collection_num, sample_size) %>%
mutate(sample_size = replace_na(sample_size, 0)) %>%
mutate(total = sum(sample_size),
percentage = sample_size / total,
collection_date = lubridate::as_date(collection_date)) %>%
ggplot(aes(x = collection_date, y = percentage, fill = sp_name)) +
geom_area() +
scale_fill_manual(values = species_cols) +
scale_y_continuous(breaks = c(0,1)) +
labs(x = "Collection Date",
y = "Proportion",
fill = "Species") +
theme_minimal(base_size = 20) +
theme(panel.grid = element_blank(),
axis.ticks = element_line())

pathogen_cols = c("no" = "grey95", "cloudy" = "honeydew3", "spot" = "antiquewhite3", "other" = "tomato3")
full_data %>%
select(collection_date, dev_eggs, pathogen, lipids, sp_name, sex) %>%
group_by() %>%
filter(sex != "juvenile") %>%
group_by(collection_date) %>%
count(pathogen) %>%
filter(pathogen != "uncertain") %>%
pivot_wider(id_cols = "collection_date",
names_from = pathogen,
values_from = n,
values_fill = 0) %>%
mutate(total = sum(no, cloudy, spot, other)) %>%
pivot_longer(cols = c(no, cloudy, spot, other),
names_to = "pathogen",
values_to = "count") %>%
mutate(percent = count/total,
collection_date = lubridate::as_date(collection_date),
pathogen = fct_relevel(pathogen, "no", "cloudy", "spot", "other")) %>%
ggplot(aes(x = collection_date, y = percent, fill = pathogen)) +
geom_area() +
scale_fill_manual(values = pathogen_cols) +
scale_y_continuous(breaks = c(0,1)) +
labs(x = "Collection Date",
y = "Proportion",
fill = "Pathogen") +
theme_minimal(base_size = 20) +
theme(panel.grid = element_blank(),
axis.ticks = element_line())

dev_eggs_cols = c("no" = "grey95", "yes" = "lightblue3")
full_data %>%
select(collection_date, dev_eggs, pathogen, lipids, sp_name, sex) %>%
group_by(sp_name) %>%
filter(sex != "juvenile") %>%
group_by(sp_name, collection_date) %>%
count(dev_eggs) %>%
filter(dev_eggs != "uncertain") %>%
pivot_wider(id_cols = c("collection_date", "sp_name"),
names_from = dev_eggs,
values_from = n,
values_fill = 0) %>%
mutate(total = sum(no, yes)) %>%
pivot_longer(cols = c(no, yes),
names_to = "dev_eggs",
values_to = "count") %>%
mutate(percent = count/total,
collection_date = lubridate::as_date(collection_date),
dev_eggs = fct_relevel(dev_eggs, "no", "yes")) %>%
ungroup() %>%
complete(collection_date, nesting(sp_name, dev_eggs), fill = list(percent = 1)) %>%
mutate(percent = if_else(is.na(total) & dev_eggs == "yes", 0, percent)) %>%
ggplot(aes(x = collection_date, y = percent, fill = dev_eggs)) +
facet_wrap(sp_name~., ncol = 1) +
geom_area() +
scale_fill_manual(values = dev_eggs_cols) +
scale_y_continuous(breaks = c(0,1)) +
labs(x = "Collection Date",
y = "Proportion",
fill = "Developing \nEggs") +
theme_minimal(base_size = 20) +
theme(panel.grid = element_blank(),
axis.ticks = element_line())

lipid_cols = c("no" = "grey95", "yes" = "sienna2")
full_data %>%
select(collection_date, dev_eggs, pathogen, lipids, sp_name, sex) %>%
group_by(sp_name) %>%
filter(sex != "juvenile") %>%
group_by(sp_name, collection_date) %>%
count(lipids) %>%
filter(lipids != "uncertain") %>%
pivot_wider(id_cols = c("collection_date", "sp_name"),
names_from = lipids,
values_from = n,
values_fill = 0) %>%
mutate(total = sum(no, yes)) %>%
pivot_longer(cols = c(no, yes),
names_to = "lipids",
values_to = "count") %>%
mutate(percent = count/total,
collection_date = lubridate::as_date(collection_date),
lipids = fct_relevel(lipids, "no", "yes")) %>%
ungroup() %>%
complete(collection_date, nesting(sp_name, lipids), fill = list(percent = 1)) %>%
mutate(percent = if_else(is.na(total) & lipids == "yes", 0, percent)) %>%
ggplot(aes(x = collection_date, y = percent, fill = lipids)) +
facet_wrap(sp_name~., ncol = 1) +
geom_area() +
scale_fill_manual(values = lipid_cols) +
scale_y_continuous(breaks = c(0,1)) +
labs(x = "Collection Date",
y = "Proportion",
fill = "Lipids\nPresent") +
theme_minimal(base_size = 20) +
theme(panel.grid = element_blank(),
axis.ticks = element_line())

Temperature Variability
Lake Champlain is highly seasonal, with both average temperatures and
temperature variability changing throughout the year. These patterns in
the experienced thermal environment may drive the observed variation in
copepod thermal limits. However, the time period affecting copepod
thermal limits is unknown. Depending the on the duration of time
considered, there are large changes in the experienced environment, in
particular regarding the temperature range and variance. Consider for
example three time periods: the day of collection, one week prior to
collection, and four weeks prior to collection. While the overall
pattern is similar, we can see that, unsurprisingly, considering longer
periods of time results in larger ranges and slightly changes the
pattern of variance experienced.
## Daily values
daily_temp_data = temp_data %>%
ungroup() %>%
group_by(date) %>%
summarise(mean_temp = mean(temp),
med_temp = median(temp),
var_temp = var(temp),
min_temp = min(temp),
max_temp = max(temp)) %>%
mutate("range_temp" = max_temp - min_temp)
day_prior_temp_data = temp_data %>%
ungroup() %>%
group_by(date) %>%
summarise(mean_temp = mean(temp),
med_temp = median(temp),
var_temp = var(temp),
min_temp = min(temp),
max_temp = max(temp)) %>%
mutate(date = date + 1) %>%
rename_with(.fn = ~ paste0("prior_day_", .x), .cols = c(-date))
daily_plot = daily_temp_data %>%
pivot_longer(cols = c(-date),
names_to = "parameter",
values_to = "temp") %>%
ggplot(aes(x = date, y = temp, colour = parameter)) +
geom_line(linewidth = 1) +
scale_colour_manual(values = c(
"mean_temp" = "olivedrab3",
"med_temp" = "seagreen3",
"max_temp" = "tomato",
"min_temp" = "dodgerblue",
"range_temp" = "goldenrod3",
"var_temp" = "darkgoldenrod1"
)) +
scale_x_continuous(breaks = as.Date(c("2023-01-01", "2023-04-01", "2023-07-01"))) +
ggtitle("Daily Values") +
labs(y = "Temperature (°C)",
x = "") +
theme_bw(base_size = 20) +
theme(panel.grid = element_blank(),
axis.text.x = element_text(angle = 270, hjust = 0, vjust = 0.5))
## Defining the function to get predictor values for periods of different lengths
get_predictors = function(daily_values, raw_temp, n_days){
prefix = str_replace_all(xfun::numbers_to_words(n_days), pattern = " ", replacement = "-")
mean_values = daily_values %>%
ungroup() %>%
mutate(mean_max = slide_vec(.x = max_temp, .f = mean, .before = n_days, .complete = T),
mean_min = slide_vec(.x = min_temp, .f = mean, .before = n_days, .complete = T),
mean_range = slide_vec(.x = range_temp, .f = mean, .before = n_days, .complete = T)) %>%
select(date, mean_max, mean_min, mean_range) %>%
rename_with( ~ paste(prefix, "day", .x, sep = "_"), .cols = c(-date))
period_values = raw_temp %>%
mutate(mean = slide_index_mean(temp, i = date, before = days(n_days),
na_rm = T),
max = slide_index_max(temp, i = date, before = days(n_days),
na_rm = T),
min = slide_index_min(temp, i = date, before = days(n_days),
na_rm = T),
med = slide_index_dbl(temp, .i = date, .before = days(n_days),
na_rm = T, .f = median),
var = slide_index_dbl(temp, .i = date, .before = days(n_days),
.f = var),
range = max - min) %>%
select(-temp) %>%
distinct() %>%
rename_with( ~ paste(prefix, "day", .x, sep = "_"), .cols = c(-date))%>%
inner_join(mean_values, by = c("date")) %>%
drop_na()
return(period_values)
}
# ## Getting predictor variables for different periods
#
# ### Short (three days)
# three_day_temps = get_predictors(daily_values = daily_temp_data,
# raw_temp = temp_data,
# n_days = 3)
#
# ### ONE WEEK
week_temps = get_predictors(daily_values = daily_temp_data,
raw_temp = temp_data,
n_days = 7)
week_plot = week_temps %>%
pivot_longer(cols = c(-date),
names_to = "parameter",
values_to = "temp") %>%
filter(parameter %in% c("seven_day_mean",
"seven_day_med",
"seven_day_max",
"seven_day_min",
"seven_day_var",
"seven_day_range")) %>%
mutate(parameter = paste(word(parameter, start = 3, sep = fixed("_")), "_temp", sep = "")) %>%
ggplot(aes(x = date, y = temp, colour = parameter)) +
geom_line(linewidth = 1) +
scale_colour_manual(values = c(
"mean_temp" = "olivedrab3",
"med_temp" = "seagreen3",
"max_temp" = "tomato",
"min_temp" = "dodgerblue",
"range_temp" = "goldenrod3",
"var_temp" = "darkgoldenrod1"
)) +
scale_x_continuous(breaks = as.Date(c("2023-01-01", "2023-04-01", "2023-07-01"))) +
ggtitle("One Week") +
labs(y = "Temperature (°C)",
x = "") +
theme_bw(base_size = 20) +
theme(panel.grid = element_blank(),
axis.text.x = element_text(angle = 270, hjust = 0, vjust = 0.5))
#
#
# ### TWO WEEKS
# two_week_temps = get_predictors(daily_values = daily_temp_data,
# raw_temp = temp_data,
# n_days = 14)
#
# two_week_plot = two_week_temps %>%
# pivot_longer(cols = c(-date),
# names_to = "parameter",
# values_to = "temp") %>%
# filter(parameter %in% c("fourteen_day_mean",
# "fourteen_day_med",
# "fourteen_day_max",
# "fourteen_day_min",
# "fourteen_day_var",
# "fourteen_day_range")) %>%
# mutate(parameter = paste(word(parameter, start = 3, sep = fixed("_")), "_temp", sep = "")) %>%
# ggplot(aes(x = date, y = temp, colour = parameter)) +
# geom_line(linewidth = 1) +
# scale_colour_manual(values = c(
# "mean_temp" = "olivedrab3",
# "med_temp" = "seagreen3",
# "max_temp" = "tomato",
# "min_temp" = "dodgerblue",
# "range_temp" = "goldenrod3",
# "var_temp" = "darkgoldenrod1"
# )) +
# scale_x_continuous(breaks = as.Date(c("2023-01-01", "2023-04-01", "2023-07-01"))) +
# ggtitle("Two Weeks") +
# labs(y = "Temperature (°C)",
# x = "") +
# theme_bw(base_size = 20) +
# theme(panel.grid = element_blank(),
# axis.text.x = element_text(angle = 270, hjust = 0, vjust = 0.5))
#
#
# ### FOUR WEEKS
four_week_temps = get_predictors(daily_values = daily_temp_data,
raw_temp = temp_data,
n_days = 28)
four_week_plot = four_week_temps %>%
pivot_longer(cols = c(-date),
names_to = "parameter",
values_to = "temp") %>%
filter(parameter %in% c("twenty-eight_day_mean",
"twenty-eight_day_med",
"twenty-eight_day_max",
"twenty-eight_day_min",
"twenty-eight_day_var",
"twenty-eight_day_range")) %>%
mutate(parameter = paste(word(parameter, start = 3, sep = fixed("_")), "_temp", sep = "")) %>%
ggplot(aes(x = date, y = temp, colour = parameter)) +
geom_line(linewidth = 1) +
scale_colour_manual(values = c(
"mean_temp" = "olivedrab3",
"med_temp" = "seagreen3",
"max_temp" = "tomato",
"min_temp" = "dodgerblue",
"range_temp" = "goldenrod3",
"var_temp" = "darkgoldenrod1"
)) +
scale_x_continuous(breaks = as.Date(c("2023-01-01", "2023-04-01", "2023-07-01"))) +
ggtitle("Four Weeks") +
labs(y = "Temperature (°C)",
x = "") +
theme_bw(base_size = 20) +
theme(panel.grid = element_blank(),
axis.text.x = element_text(angle = 270, hjust = 0, vjust = 0.5))
#
#
# ### EIGHT WEEKS
# eight_week_temps = get_predictors(daily_values = daily_temp_data,
# raw_temp = temp_data,
# n_days = 56)
#
# eight_week_plot = eight_week_temps %>%
# pivot_longer(cols = c(-date),
# names_to = "parameter",
# values_to = "temp") %>%
# filter(parameter %in% c("fifty-six_day_mean",
# "fifty-six_day_med",
# "fifty-six_day_max",
# "fifty-six_day_min",
# "fifty-six_day_var",
# "fifty-six_day_range")) %>%
# mutate(parameter = paste(word(parameter, start = 3, sep = fixed("_")), "_temp", sep = "")) %>%
# ggplot(aes(x = date, y = temp, colour = parameter)) +
# geom_line(linewidth = 1) +
# scale_colour_manual(values = c(
# "mean_temp" = "olivedrab3",
# "med_temp" = "seagreen3",
# "max_temp" = "tomato",
# "min_temp" = "dodgerblue",
# "range_temp" = "goldenrod3",
# "var_temp" = "darkgoldenrod1"
# )) +
# scale_x_continuous(breaks = as.Date(c("2023-01-01", "2023-04-01", "2023-07-01"))) +
# ggtitle("Eight Weeks") +
# labs(y = "Temperature (°C)",
# x = "") +
# theme_bw(base_size = 20) +
# theme(panel.grid = element_blank(),
# axis.text.x = element_text(angle = 270, hjust = 0, vjust = 0.5))
#
ggarrange(daily_plot, week_plot, four_week_plot,
common.legend = T, nrow = 1, legend = "bottom")

The different time periods examined by this climate data highlights
that the relationship between minimum and maximum temperatures changes
based on the window examined. For example, minimum and maximum
temperatures experienced over weekly intervals are closely linked,
whereas there is a distinct seasonal cycle in the relationship between
minimum and maximum temperatures experienced over periods of four
weeks.
one_week_doy_data = week_temps %>%
mutate(doy = yday(date))
one_week_temp_circle = ggplot(one_week_doy_data, aes(x = seven_day_mean_max, y = seven_day_mean_min, colour = doy)) +
geom_point() +
scale_colour_gradient2(
high = "dodgerblue4",
mid = "coral2",
low = "dodgerblue4",
midpoint = 182.5) +
labs(x = "Max. Temp. (°C)",
y = "Min. Temp. (°C)") +
labs(x = "Max. Temp. (°C)",
y = "Min. Temp. (°C)") +
ggtitle("One Week") +
theme_matt()
four_week_doy_data = four_week_temps %>%
mutate(doy = yday(date))
four_week_temp_circle = ggplot(four_week_doy_data, aes(x = `twenty-eight_day_max`, y = `twenty-eight_day_min`, colour = doy)) +
geom_point() +
scale_colour_gradient2(
high = "dodgerblue4",
mid = "coral2",
low = "dodgerblue4",
midpoint = 182.5) +
labs(x = "Max. Temp. (°C)",
y = "Min. Temp. (°C)") +
ggtitle("Four Week") +
theme_matt()
ggarrange(one_week_temp_circle, four_week_temp_circle,
common.legend = T, legend = "bottom")

The thermal environment over any period of time may drive patterns in
thermal acclimation. To explore the potential effects of different
acclimation windows, we examined the correlation between thermal limits
and different representations of the thermal environment for different
periods of time. Shown below are the correlation coefficients for these
relationships. Each facet shows the relationship for a different
dimension of the thermal environment. Correlation coefficients are
plotted for different durations, for species that were collected more
than five times. Only data for mature female copepods was included.
We can see that, in general, copepods are responding to proximate
cues from the thermal environment, with correlations generally dropping
off substantially as acclimation window duration increases. An exception
is Epischura lacustris, which appears to be responding to
maximum temperatures experienced over a 20 day time period.
### Pulling predictors and measuring correlations for much finer timescales; 1-56 days
num_colls = full_data %>%
filter(sex == "female") %>%
select(collection_date, sp_name) %>%
distinct() %>%
count(sp_name) %>%
filter(n >= 5)
corr_vals = data.frame()
dur_vals = c(1:50)
for(i in dur_vals){
duration_temps = get_predictors(daily_values = daily_temp_data,
raw_temp = temp_data,
n_days = i) %>%
filter(date %in% as_date(unique(full_data$collection_date)))
corr_data = full_data %>%
filter(sp_name %in% num_colls$sp_name) %>%
filter(sex == "female") %>%
mutate(collection_date = as.Date(collection_date)) %>%
inner_join(duration_temps, join_by(collection_date == date)) %>%
pivot_longer(cols = c(collection_temp, contains("day_")),
values_to = "value",
names_to = "predictor") %>%
group_by(sp_name, predictor) %>%
summarise(correlation = cor.test(ctmax, value)$estimate,
p.value = cor.test(ctmax, value)$p.value,
ci_low = cor.test(ctmax, value)$conf.int[1],
ci_high = cor.test(ctmax, value)$conf.int[2],
.groups = "keep") %>%
filter(predictor != "collection_temp") %>%
mutate(sig = ifelse(p.value <0.05, "Sig.", "Non Sig.")) %>%
separate(predictor, "_day_", into = c(NA, "parameter")) %>%
mutate(duration = i)
corr_vals = bind_rows(corr_vals, corr_data)
}
coll_corr = full_data %>%
filter(sp_name %in% num_colls$sp_name) %>%
filter(sex == "female") %>%
group_by(sp_name) %>%
summarise(correlation = cor.test(ctmax, collection_temp)$estimate,
p.value = cor.test(ctmax, collection_temp)$p.value,
ci_low = cor.test(ctmax, collection_temp)$conf.int[1],
ci_high = cor.test(ctmax, collection_temp)$conf.int[2]) %>%
mutate(sig = ifelse(p.value <0.05, "Sig.", "Non Sig.")) %>%
mutate(duration = 0,
parameter = "coll_temp")
corr_vals = corr_vals %>%
mutate(duration = as.numeric(duration)) %>%
bind_rows(coll_corr)
corr_vals %>%
mutate(parameter = fct_relevel(parameter, c("min", "max", "range",
"mean", "med", "var",
"mean_min", "mean_max", "mean_range"))) %>%
ggplot(aes(x = duration, y = correlation, colour = sp_name)) +
facet_wrap(.~parameter) +
geom_hline(yintercept = 0) +
geom_point(size = 0.9) +
geom_line(linewidth = 1.5) +
scale_colour_manual(values = species_cols) +
labs(x = "Duration (days)",
y = "Correlation",
colour = "Species") +
theme_matt_facets()

Shown here are the top three factors for each species.
#
# corr_vals = full_data %>%
# filter(sp_name %in% num_colls$sp_name) %>%
# filter(sex == "female") %>%
# mutate(collection_date = as.Date(collection_date)) %>%
# full_join(temp_predictors, join_by(collection_date == date)) %>%
# pivot_longer(cols = c(collection_temp, mean_temp:tail(names(.), 1)),
# values_to = "value",
# names_to = "predictor") %>%
# group_by(sp_name, predictor) %>%
# summarise(correlation = cor.test(ctmax, value)$estimate,
# p.value = cor.test(ctmax, value)$p.value,
# ci_low = cor.test(ctmax, value)$conf.int[1],
# ci_high = cor.test(ctmax, value)$conf.int[2]) %>%
# mutate(sig = ifelse(p.value <0.05, "Sig.", "Non Sig."))
corr_vals %>%
filter(sig == "Sig.") %>%
drop_na(correlation) %>%
group_by(sp_name) %>%
arrange(desc(correlation)) %>%
slice_head(n = 3) %>%
select("Species" = sp_name, "Predictor" = parameter, "Duration" = duration, "Correlation" = correlation, "P-Value" = p.value) %>%
knitr::kable(align = "c")
| Epischura lacustris |
max |
20 |
0.8926416 |
0.0000000 |
| Epischura lacustris |
max |
19 |
0.8906963 |
0.0000000 |
| Epischura lacustris |
max |
21 |
0.8874924 |
0.0000000 |
| Leptodiaptomus minutus |
max |
6 |
0.7902471 |
0.0000000 |
| Leptodiaptomus minutus |
max |
8 |
0.7900914 |
0.0000000 |
| Leptodiaptomus minutus |
max |
7 |
0.7900796 |
0.0000000 |
| Leptodiaptomus sicilis |
var |
21 |
0.3036325 |
0.0000000 |
| Leptodiaptomus sicilis |
range |
23 |
0.3030822 |
0.0000000 |
| Leptodiaptomus sicilis |
range |
24 |
0.3019057 |
0.0000000 |
| Limnocalanus macrurus |
max |
7 |
0.5521216 |
0.0001239 |
| Limnocalanus macrurus |
max |
8 |
0.5520367 |
0.0001242 |
| Limnocalanus macrurus |
mean_min |
6 |
0.5512902 |
0.0001274 |
| Senecella calanoides |
var |
7 |
0.4342229 |
0.0492015 |
| Skistodiaptomus oregonensis |
max |
2 |
0.8070436 |
0.0000000 |
| Skistodiaptomus oregonensis |
max |
1 |
0.8014254 |
0.0000000 |
| Skistodiaptomus oregonensis |
mean_max |
2 |
0.8009108 |
0.0000000 |
Phenotypic variation (like acclimation of thermal limits) is a
physiological process. depending on the mechanistic underpinnings
(changes in HSP expression, etc.), the amount of time it takes for an
individual to acclimate may vary based on body size (larger species,
more cells, more time required to acclimate). Shown here is the duration
of the environmental acclimation window the copepods appear to be
responding to.
mean_sizes = full_data %>%
filter(sex == "female") %>%
group_by(sp_name) %>%
summarise(mean_size = mean(size, na.rm = T))
corr_vals %>%
group_by(sp_name) %>%
filter(correlation == max(correlation)) %>%
inner_join(mean_sizes, by = "sp_name") %>%
select(sp_name, duration, mean_size) %>%
ggplot(aes(x = mean_size, y = duration)) +
geom_point(aes(colour = sp_name),
size = 4) +
scale_colour_manual(values = species_cols) +
labs(x = "Mean Female Size (mm)",
y = "Acclimation Duration",
colour = "Species") +
theme_matt() +
theme(legend.position = "right")

Trait Variation
# ctmax_plot = full_data %>%
# mutate( #sp_name = str_replace(sp_name, pattern = " ",
# # replacement = "\n"),
# sp_name = fct_reorder(sp_name, ctmax, mean)) %>%
# ggplot(aes(y = sp_name, x = ctmax)) +
# geom_point(aes(colour= sp_name_sub),
# position = position_dodge(width = 0.3),
# size = 4) +
# scale_colour_manual(values = species_cols) +
# xlab(NULL) +
# labs(y = "",
# x = "CTmax (°C)",
# colour = "Group") +
# theme_matt() +
# theme(legend.position = "none")
#
# size_plot = full_data %>%
# mutate(sp_name = fct_reorder(sp_name, ctmax, mean)) %>%
# ggplot(aes(y = sp_name, x = size)) +
# geom_point(aes(colour= sp_name_sub),
# position = position_dodge(width = 0.3),
# size = 4) +
# scale_colour_manual(values = species_cols) +
# labs(x = "Prosome Length (mm)",
# y = "",
# colour = "Group") +
# guides(color = guide_legend(ncol = 1)) +
# theme_matt(base_size = ) +
# theme(legend.position = "right",
# axis.text.y = element_blank(),
# plot.margin = margin(0, 0, 0, 0,"cm"))
#
# trait_plot = ctmax_plot + size_plot
# trait_plot
Shown below are the clutch size distributions for the three
diaptomiid species, which produce egg sacs that allow for easy
quantification of fecundity.
full_data %>%
drop_na(fecundity) %>%
ggplot(aes(x = fecundity, fill = sp_name_sub)) +
facet_wrap(.~sp_name_sub, ncol = 1) +
geom_histogram(binwidth = 2) +
scale_fill_manual(values = species_cols) +
labs(x = "Fecundity (# Eggs)") +
theme_matt_facets() +
theme(legend.position = "none")

One of the main aims of this project is to examine the patterns and
processes driving variation in upper thermal limits across these species
of copepods.
Variation with temperature
We expect one of the primary drivers of copepod thermal limits to be
temperature. The correlation analysis has shown that the copepods are
generally (although not always) responding to the recent thermal
environment. Shown below are thermal limits, body size, and fecundity
values plotted against the temperature at the time of collection. Also
shown is warming tolerance, calculated as the difference between upper
thermal limit and the collection temperature.
We generally see an increase in thermal limits with increasing
collection temperature, a slight decrease in body size, and variable
relationships between temperature and fecundity. All species maintained
some degree of buffer between environmental temperatures and upper
thermal limits, but Epischura and L. minutus
approached their upper thermal limits during the warmest collections
during the summer.
ctmax_temp = ggplot(full_data, aes(x = collection_temp, y = ctmax, colour = sp_name)) +
geom_smooth(method = "lm", linewidth = 3) +
geom_point(size = 3) +
labs(x = "Collection Temperature (°C)",
y = "CTmax (°C)",
colour = "Species") +
scale_colour_manual(values = species_cols) +
theme_matt() +
theme(legend.position = "right")
size_temp = ggplot(filter(full_data, sex != "juvenile"), aes(x = collection_temp, y = size, colour = sp_name)) +
geom_smooth(method = "lm", linewidth = 3) +
geom_point(size = 3) +
labs(x = "Collection Temperature (°C)",
y = "Length (mm)",
colour = "Species") +
scale_colour_manual(values = species_cols) +
theme_matt() +
theme(legend.position = "right")
wt_temp = ggplot(full_data, aes(x = collection_temp, y = warming_tol, colour = sp_name)) +
geom_smooth(method = "lm", linewidth = 3) +
geom_point(size = 3) +
labs(x = "Collection Temperature (°C)",
y = "Warming Tolerance (°C)",
colour = "Species") +
scale_colour_manual(values = species_cols) +
theme_matt() +
theme(legend.position = "right")
eggs_temp = ggplot(full_data, aes(x = collection_temp, y = fecundity, colour = sp_name)) +
geom_smooth(method = "lm", linewidth = 3) +
geom_point(size = 3) +
labs(x = "Collection Temperature (°C)",
y = "Fecundity (# Eggs)",
colour = "Species") +
scale_colour_manual(values = species_cols) +
theme_matt() +
theme(legend.position = "right")
ggarrange(ctmax_temp, size_temp, wt_temp, eggs_temp,
common.legend = T, legend = "right")

full_data %>%
#filter(sex == "female") %>%
group_by(sp_name) %>% filter(n() > 5) %>% filter(!str_detect(sp_name, pattern = "kindti")) %>%
ggplot(aes(x = collection_temp, y = ctmax, colour = sp_name)) +
facet_wrap(sp_name~.) +
geom_point(size = 2, alpha = 0.8) +
geom_smooth(method = "lm", se = F, linewidth = 2) +
labs(x = "Collection Temp. (°C)",
y = "CTmax (°C)") +
scale_colour_manual(values = species_cols) +
theme_matt() +
theme(legend.position = "none")

Temperature dependence is relatively weak in L. sicilis,
especially at cooler temperatures. We will return to this feature later
in the report, but for now we will note that there are two size morphs
in this species, which appear to respond differently to decreases in
temperature. There are significant differences between the morphs and
how temperature affects CTmax.
morph_data = full_data %>%
filter(sex == "female" & sp_name == "Leptodiaptomus sicilis") %>%
mutate(morph = if_else(size > 0.89, "large", "small"))
ggplot(morph_data, aes(x = collection_temp, y = ctmax, colour = morph)) +
geom_point(size = 2, alpha = 0.8) +
geom_smooth(method = "lm", se = T, linewidth = 2) +
labs(x = "Collection Temp. (°C)",
y = "CTmax (°C)") +
theme_matt() +
theme(legend.position = "none")

morph.model = lm(data = morph_data,
ctmax ~ collection_temp * morph)
knitr::kable(car::Anova(morph.model, type = "III", test = "F"))
| (Intercept) |
11464.46170 |
1 |
3791.83208 |
0.0000000 |
| collection_temp |
107.82264 |
1 |
35.66198 |
0.0000000 |
| morph |
35.16622 |
1 |
11.63111 |
0.0007246 |
| collection_temp:morph |
17.95299 |
1 |
5.93789 |
0.0153180 |
| Residuals |
1055.18838 |
349 |
NA |
NA |
#summary(morph.model)
#morph.em = emmeans::emmeans(morph.model, pairwise ~ morph)
#plot(morph.em)
Copepods spent several days in lab during experiments. Shown below
are the CTmax residuals (taken from a model of CTmax against collection
temperature) plotted against the time spent in lab before measurements
were made. Individual regressions are shown for the residuals against
days in lab for each collection. We can see clearly that thermal limits
are fairly stable over time.
ggplot(ctmax_resids, aes(x = days_in_lab, y = resids, colour = sp_name, group = collection_date)) +
facet_wrap(sp_name~.) +
geom_point(size = 4, alpha = 0.5) +
geom_smooth(method = "lm", se = F, linewidth = 1) +
#scale_x_continuous(breaks = c(0:5)) +
labs(x = "Days in lab",
y = "CTmax Residuals") +
scale_colour_manual(values = species_cols) +
theme_matt_facets() +
theme(legend.position = "none")

full.model = lme4::lmer(data = model_data,
ctmax ~ sex + temp_cent + size_cent +
(1 + days_in_lab + temp_cent + size_cent|sp_name))
car::Anova(full.model)
## Analysis of Deviance Table (Type II Wald chisquare tests)
##
## Response: ctmax
## Chisq Df Pr(>Chisq)
## sex 32.9478 2 7.006e-08 ***
## temp_cent 20.8535 1 4.958e-06 ***
## size_cent 1.7818 1 0.1819
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
fixed = fixef(full.model)
model_coefs = coefficients(full.model)$`sp_name` %>%
rownames_to_column(var = "species") %>%
separate(species, into = c("species"), sep = ":") %>%
select(species, "intercept" = "(Intercept)", temp_cent, size_cent, days_in_lab)
ggplot(model_coefs, aes(x = intercept, y = temp_cent)) +
geom_smooth(method = "lm", colour = "black") +
geom_point(aes(colour = species),
size = 6) +
scale_colour_manual(values = species_cols) +
labs(x = "Species Intercept",
y = "ARR") +
theme_matt() +
theme(legend.position = "right")

The term “acclimation response ratio” is often used to describe the
effect of temperature on thermal limits. The ARR is calculated as the
change in thermal limits per degree change in acclimation temperature.
For our data, we will estimate ARR as the slope of CTmax against
collection temperature. These slopes were taken from a regression of
CTmax against collection temperature and body size. Two different model
types were used, a simple linear regression and a mixed effects model.
The estimated ARR values were generally highly similar between the model
types used.
Sex and stage variation in thermal limits
Previous sections have generally lumped juvenile, female, and male
individuals together. There may be important stage- or sex-specific
differences in CTmax though. For several species, we have measurements
for individuals in different stages or of different sexes.
sex_sample_sizes = ctmax_resids %>%
group_by(sp_name, sex) %>%
summarise(num = n()) %>%
pivot_wider(id_cols = sp_name,
names_from = sex,
values_from = num,
values_fill = 0) %>%
select("Species" = sp_name, "Juvenile" = juvenile, "Female" = female, "Male" = male)
knitr::kable(sex_sample_sizes, align = "c")
| Epischura lacustris |
26 |
45 |
19 |
| Leptodiaptomus minutus |
11 |
254 |
35 |
| Leptodiaptomus sicilis |
31 |
353 |
93 |
| Limnocalanus macrurus |
4 |
43 |
39 |
| Osphranticum labronectum |
0 |
1 |
0 |
| Senecella calanoides |
11 |
21 |
8 |
| Skistodiaptomus oregonensis |
14 |
194 |
28 |
The female-male and female-juvenile comparisons show that there are
generally no differences in thermal limits between these groups.
ctmax_resids %>%
filter(sp_name %in% filter(sex_sample_sizes, Male > 0, Female > 0)$Species &
sex != "juvenile") %>%
ggplot(aes(x = sex, y = resids, colour = sp_name, group = sp_name)) +
facet_wrap(sp_name~., ncol = 2) +
geom_smooth(method = "lm", se = F, linewidth = 1) +
geom_point(size = 3,
alpha = 0.5,
position = position_jitter(height = 0, width = 0.05)) +
labs(x = "Sex",
y = "CTmax Residuals") +
scale_colour_manual(values = species_cols) +
theme_bw(base_size = 18) +
theme(legend.position = "none",
panel.grid = element_blank())

ctmax_resids %>%
filter(sp_name %in% filter(sex_sample_sizes, Juvenile > 0 & Female > 0)$Species &
sex != "male") %>%
ggplot(aes(x = sex, y = resids, colour = sp_name, group = sp_name)) +
facet_wrap(sp_name~., ncol = 2) +
geom_smooth(method = "lm", se = F, linewidth = 1) +
geom_point(size = 3,
alpha = 0.5,
position = position_jitter(height = 0, width = 0.05)) +
labs(x = "Sex",
y = "CTmax (°C)") +
scale_colour_manual(values = species_cols) +
theme_bw(base_size = 18) +
theme(legend.position = "none",
panel.grid = element_blank())

Trait Correlations and Trade-offs
A relationship between size and upper thermal limits has been
suggested in a wide range of other taxa. Shown below are the measured
upper thermal limits plotted against prosome length. The overall
relationship (inclusive of all species) is shown as the black line in
the background. Regressions for each individual species are also shown.
Across the entire assemblage, there is a strong decrease in thermal
limits with increasing size.
full_data %>%
#filter(sex == "female") %>%
ggplot( aes(x = size, y = ctmax, colour = sp_name)) +
geom_smooth(data = full_data,
aes(x = size, y = ctmax),
method = "lm",
colour ="black",
linewidth = 2.5) +
geom_point(size = 2, alpha = 0.3) +
geom_smooth(method = "lm", se = F, linewidth = 2) +
labs(x = "Length (mm)",
y = "CTmax (°C)",
colour = "Species") +
scale_colour_manual(values = species_cols) +
theme_matt() +
theme(legend.position = "right")

Shown here is the relationship for each species individually.
full_data %>%
#filter(sex == "female") %>%
group_by(sp_name) %>% filter(n() >2) %>% filter(!str_detect(sp_name, pattern = "kindti")) %>%
ggplot( aes(x = size, y = ctmax, colour = sp_name)) +
facet_wrap(sp_name~., scales = "free", nrow = 2) +
geom_point(size = 2, alpha = 0.8) +
geom_smooth(method = "lm", se = F, linewidth = 2) +
labs(x = "Length (mm)",
y = "CTmax (°C)",
colour = "Species") +
scale_colour_manual(values = species_cols) +
theme_matt() +
theme(legend.position = "none")

Shown below is the relationship between mean size and mean thermal
limits for females of each species. We see that larger species within
the community tend to have a lower thermal limit than smaller
species.
full_data %>%
group_by(sp_name, sex) %>%
summarize(mean_ctmax = mean(ctmax, na.rm = T),
mean_size = mean(size, na.rm = T)) %>%
#filter(sex == "female") %>%
ggplot(aes(x = mean_size, y = mean_ctmax)) +
geom_smooth(method = "lm", se = F, linewidth = 2, colour = "black") +
geom_point(aes(colour = sp_name, shape = sex),
size = 5) +
labs(x = "Length (mm)",
y = "CTmax (°C)",
colour = "Species") +
scale_colour_manual(values = species_cols) +
theme_matt() +
theme(legend.position = "right")

Shown here is the relationship between fecundity and size, showing
the classic pattern of increasing egg production with increasing
size.
ctmax_resids %>%
drop_na(fecundity) %>%
ggplot(aes(x = size, y = fecundity, colour = sp_name)) +
geom_smooth(method = "lm", se = F, linewidth = 2) +
geom_point(size = 2, alpha = 0.5) +
labs(x = "Prosome length (mm)",
y = "Fecundity (# Eggs)",
colour = "Species") +
scale_colour_manual(values = species_cols) +
theme_matt() +
theme(legend.position = "right")

Individuals may also allocate energy to different fitness related
traits, prioritizing reproductive output over environmental tolerance,
for example. Shown below is the relationship between CTmax residuals
(again, controlling for the effects of collection temperature) against
fecundity. We can see clearly that individuals with increased fecundity
are not decreasing thermal limits, suggesting that there is no energetic
trade-off between these traits.
ctmax_resids %>%
drop_na(fecundity) %>%
ggplot(aes(x = resids, y = fecundity, colour = sp_name)) +
geom_smooth(method = "lm", se = F, linewidth = 2) +
geom_point(size = 2, alpha = 0.5) +
labs(x = "CTmax Residuals",
y = "Fecundity (# Eggs)") +
scale_colour_manual(values = species_cols) +
theme_matt() +
theme(legend.position = "right")

fitness.model = lm(data = ctmax_resids,
fecundity ~ resids * sp_name)
car::Anova(fitness.model)
## Anova Table (Type II tests)
##
## Response: fecundity
## Sum Sq Df F value Pr(>F)
## resids 0.0 1 0.0000 0.998808
## sp_name 8278.1 2 269.1981 < 2.2e-16 ***
## resids:sp_name 202.6 2 6.5895 0.001558 **
## Residuals 5196.9 338
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
emmeans::emtrends(fitness.model, var = "resids","sp_name")
## sp_name resids.trend SE df lower.CL upper.CL
## Leptodiaptomus minutus 0.4600 0.267 338 -0.0645 0.985
## Leptodiaptomus sicilis 0.0731 0.204 338 -0.3290 0.475
## Skistodiaptomus oregonensis -1.2274 0.387 338 -1.9880 -0.467
##
## Confidence level used: 0.95
Other patterns in variation
Leptodiaptomus sicilis is the most abundant species during
the winter. There was a large shift in the size of mature females
towards the end of December. These large and small individuals are the
same species (confirmed via COI sequencing), suggesting this shift may
reflect a transition from one generation to another and that, unlike in
many other lakes, there are two generations of L. sicilis per
year in Lake Champlain. This size difference may be caused by
differences in the developmental environments. For example, individuals
developing in January grow up at very low temperatures, and therefore
may reach larger sizes. These individuals oversummer in deep waters,
then re-emerge in October and produce a new generation. Water
temperatures are still fairly high through November, which results in a
generation of smaller individuals, which mature in time to produce a new
generation in January.
Shown below is the distribution of pairwise distances between COI
sequences of large and small morphs. Distances in both within- and
across-morph comparisons are small.
ind_dist = ape::dist.dna(sic_dnabin, model = "raw") %>% as.matrix %>%
as_tibble() %>%
mutate("ind1" = colnames(.)) %>%
pivot_longer(-ind1, names_to = "ind2", values_to = "dist") %>%
mutate(ind1 = factor(ind1),
ind2 = factor(ind2)) %>%
filter(!(ind1 == "sore1" | ind2 == "sore1")) %>%
mutate(
ind1 = case_when(
ind1 == "S1" ~ "small1",
ind1 == "S3" ~ "small3",
ind1 == "lsic3" ~ "small4",
ind1 == "lsic5" ~ "small6",
ind1 == "lsic9" ~ "small8",
ind1 == "lsic10" ~ "small9",
ind1 == "lsic11" ~ "small10",
ind1 == "L1" ~ "large1",
ind1 == "L2" ~ "large2",
ind1 == "L3" ~ "large3",
ind1 == "lsic1" ~ "large4",
ind1 == "lsic2" ~ "large5",
ind1 == "lsic7" ~ "large6",
ind1 == "lsic8" ~ "large7"),
ind2 = case_when(
ind2 == "S1" ~ "small1",
ind2 == "S3" ~ "small3",
ind2 == "lsic3" ~ "small4",
ind2 == "lsic5" ~ "small6",
ind2 == "lsic9" ~ "small8",
ind2 == "lsic10" ~ "small9",
ind2 == "lsic11" ~ "small10",
ind2 == "L1" ~ "large1",
ind2 == "L2" ~ "large2",
ind2 == "L3" ~ "large3",
ind2 == "lsic1" ~ "large4",
ind2 == "lsic2" ~ "large5",
ind2 == "lsic7" ~ "large6",
ind2 == "lsic8" ~ "large7"),
'comparison' = case_when(
str_detect(ind1, pattern = "large") & str_detect(ind2, pattern = "large") ~ "within",
str_detect(ind1, pattern = "small") & str_detect(ind2, pattern = "small") ~ "within",
str_detect(ind1, pattern = "large") & str_detect(ind2, pattern = "small") ~ "across",
str_detect(ind1, pattern = "small") & str_detect(ind2, pattern = "large") ~ "across"
))
ggplot(ind_dist, aes(dist, fill = comparison)) +
geom_histogram(binwidth = 0.005) +
labs(x = "Distance") +
theme_matt()

full_data %>%
filter(sp_name == "Leptodiaptomus sicilis") %>%
filter(sex != "juvenile") %>%
group_by(collection_date) %>%
mutate(size_center = scale(size, center = T, scale = F)) %>%
ggplot(aes(y = collection_date, x = size, fill = collection_temp)) +
facet_wrap(sex~.) +
geom_density_ridges(bandwidth = 0.04) +
geom_vline(xintercept = 0.89) +
labs(x = "Size (mm)",
y = "Date",
fill = "Coll. Temp. (°C)") +
theme_matt() +
theme(legend.position = "right",
axis.text.y = element_text(size = 12))

full_data %>%
filter(sp_name == "Leptodiaptomus minutus") %>%
filter(sex != "juvenile") %>%
ggplot(aes(y = collection_date, x = size, fill = collection_temp)) +
facet_wrap(sex~.) +
geom_density_ridges(bandwidth = 0.04) +
geom_vline(xintercept = 0.69) +
labs(x = "Size (mm)",
y = "Date",
fill = "Coll. Temp. (°C)") +
coord_cartesian(xlim = c(0.5,0.9)) +
theme_matt() +
theme(legend.position = "right",
axis.text.y = element_text(size = 12))

Distribution Lag Non-Linear Model (DLNM approach)
dlnm_data = full_data %>%
filter(sex == "female") %>%
select(collection_date, days_in_lab, collection_temp, replicate, sp_name, size, fecundity, ctmax) %>%
group_by(collection_date, collection_temp, sp_name) %>%
summarise(mean_ctmax = mean(ctmax, na.rm = T),
mean_size = mean(size, na.rm = T),
sample = n())
hourly_temps = raw_temps %>%
mutate(hour = lubridate::hour(dateTime)) %>%
group_by(date, hour) %>%
summarise(mean_temp = mean(degC)) %>%
ungroup() %>%
complete(date, nesting(hour)) %>%
mutate(timestep = ymd_hms(
paste(lubridate::as_date(date),
paste0(hour, ":00:00"), sep = " ")),
observation = row_number())
if(predict_vuln == F){
knitr::knit_exit()
}
LS0tCnRpdGxlOiBTZWFzb25hbGl0eSBpbiBMYWtlIENoYW1wbGFpbiBDb3BlcG9kIFRoZXJtYWwgTGltaXRzCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OgogICAgICAgICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICAgICAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICAgICAgICB0b2M6IHRydWUKICAgICAgICAgIHRvY19mbG9hdDogdHJ1ZQogIGdpdGh1Yl9kb2N1bWVudDoKICAgICAgICAgIGh0bWxfcHJldmlldzogZmFsc2UKICAgICAgICAgIHRvYzogdHJ1ZQogICAgICAgICAgdG9jX2RlcHRoOiAzCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9VCwgbWVzc2FnZSA9IEYsIHdhcm5pbmcgPSBGLCBlY2hvID0gRn0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGVjaG8gPSBrbml0cjo6aXNfaHRtbF9vdXRwdXQoKSwKICBmaWcuYWxpZ24gPSAiY2VudGVyIiwKICBmaWcucGF0aCA9ICIuLi9GaWd1cmVzL21hcmtkb3duLyIsCiAgZGV2ID0gYygicG5nIiwgInBkZiIpLAogIG1lc3NhZ2UgPSBGQUxTRSwKICB3YXJuaW5nID0gRkFMU0UsCiAgY29sbGFwc2UgPSBUCikKCnRoZW1lX21hdHQgPSBmdW5jdGlvbihiYXNlX3NpemUgPSAxOCwKICAgICAgICAgICAgICAgICAgICAgIGRhcmtfdGV4dCA9ICJncmV5MjAiKXsKICBtaWRfdGV4dCA8LSAgbW9ub2Nocm9tZVI6OmdlbmVyYXRlX3BhbGV0dGUoZGFya190ZXh0LCAiZ29fbGlnaHRlciIsIG5fY29sb3VycyA9IDUpWzJdCiAgbGlnaHRfdGV4dCA8LSAgbW9ub2Nocm9tZVI6OmdlbmVyYXRlX3BhbGV0dGUoZGFya190ZXh0LCAiZ29fbGlnaHRlciIsIG5fY29sb3VycyA9IDUpWzNdCiAgCiAgZ2dwdWJyOjp0aGVtZV9wdWJyKGJhc2VfZmFtaWx5PSJzYW5zIikgJStyZXBsYWNlJSAKICAgIHRoZW1lKAogICAgICBwYW5lbC5iYWNrZ3JvdW5kICA9IGVsZW1lbnRfcmVjdChmaWxsPSJ0cmFuc3BhcmVudCIsIGNvbG91cj1OQSksIAogICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLCAKICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLAogICAgICBsZWdlbmQua2V5ID0gZWxlbWVudF9yZWN0KGZpbGw9InRyYW5zcGFyZW50IiwgY29sb3VyPU5BKSwKICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvdXIgPSBtaWRfdGV4dCwgbGluZWhlaWdodCA9IDEuMSksCiAgICAgIHRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUgKiAxLjUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG91ciA9IGRhcmtfdGV4dCksCiAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3VyID0gbWlkX3RleHQpLAogICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDEuMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmdpbiA9IHVuaXQoYygzLCAwLCAwLCAwKSwgIm1tIikpLAogICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDEuMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmdpbiA9IHVuaXQoYygwLCA1LCAwLCAwKSwgIm1tIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5nbGUgPSA5MCksCiAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9YmFzZV9zaXplICogMC45KSwKICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUgKiAwLjksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFjZSA9ICJib2xkIiksCiAgICAgIHBsb3QubWFyZ2luID0gbWFyZ2luKDAuMjUsIDAuMjUsIDAuMjUsIDAuMjUsImNtIikKICAgICkKfQoKdGhlbWVfbWF0dF9mYWNldHMgPSBmdW5jdGlvbihiYXNlX3NpemUgPSAxOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXJrX3RleHQgPSAiZ3JleTIwIil7CiAgbWlkX3RleHQgPC0gIG1vbm9jaHJvbWVSOjpnZW5lcmF0ZV9wYWxldHRlKGRhcmtfdGV4dCwgImdvX2xpZ2h0ZXIiLCBuX2NvbG91cnMgPSA1KVsyXQogIGxpZ2h0X3RleHQgPC0gIG1vbm9jaHJvbWVSOjpnZW5lcmF0ZV9wYWxldHRlKGRhcmtfdGV4dCwgImdvX2xpZ2h0ZXIiLCBuX2NvbG91cnMgPSA1KVszXQogIAogIHRoZW1lX2J3KGJhc2VfZmFtaWx5PSJzYW5zIikgJStyZXBsYWNlJSAKICAgIHRoZW1lKAogICAgICBwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLAogICAgICBwYW5lbC5iYWNrZ3JvdW5kICA9IGVsZW1lbnRfcmVjdChmaWxsPSJ0cmFuc3BhcmVudCIsIGNvbG91cj1OQSksIAogICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLCAKICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLAogICAgICBsZWdlbmQua2V5ID0gZWxlbWVudF9yZWN0KGZpbGw9InRyYW5zcGFyZW50IiwgY29sb3VyPU5BKSwKICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvdXIgPSBtaWRfdGV4dCwgbGluZWhlaWdodCA9IDEuMSksCiAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplKSwKICAgICAgdGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDEuNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3VyID0gZGFya190ZXh0KSwKICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSBtaWRfdGV4dCksCiAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplICogMS4yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luID0gdW5pdChjKDMsIDAsIDAsIDApLCAibW0iKSksCiAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplICogMS4yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luID0gdW5pdChjKDAsIDUsIDAsIDApLCAibW0iKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmdsZSA9IDkwKSwKICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT1iYXNlX3NpemUgKiAwLjkpLAogICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDAuOSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWNlID0gImJvbGQiKSwKICAgICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4oMC4yNSwgMC4yNSwgMC4yNSwgMC4yNSwiY20iKQogICAgKQp9CgpzcGVjaWVzX2NvbHMgPSBjKCJMZXB0b2RpYXB0b211cyBtaW51dHVzIiA9ICIjZmZkMDI5IiwKICAgICAgICAgICAgICAgICAiTGVwdG9kaWFwdG9tdXMgbWludXR1cyBqdXZlbmlsZSIgPSAiI2UzZDhhZiIsCiAgICAgICAgICAgICAgICAgIkxlcHRvZGlhcHRvbXVzIG1pbnV0dXMgbWFsZSIgPSAiI2ZmZTg5NiIsCiAgICAgICAgICAgICAgICAgIkxlcHRvZGlhcHRvbXVzIHNpY2lsaXMiID0gIiNEODZGMjkiLAogICAgICAgICAgICAgICAgICJMZXB0b2RpYXB0b211cyBzaWNpbGlzIG1hbGUiID0gIiNFMjhDMDAiLAogICAgICAgICAgICAgICAgICJTa2lzdG9kaWFwdG9tdXMgb3JlZ29uZW5zaXMiID0gIiNDNUMzNUEiLAogICAgICAgICAgICAgICAgICJTa2lzdG9kaWFwdG9tdXMgb3JlZ29uZW5zaXMgbWFsZSIgPSAiI2U2ZTZhYSIsIAogICAgICAgICAgICAgICAgICJFcGlzY2h1cmEgbGFjdXN0cmlzIGp1dmVuaWxlIiA9ICJwbHVtMSIsIAogICAgICAgICAgICAgICAgICJFcGlzY2h1cmEgbGFjdXN0cmlzIG1hbGUiID0gInBsdW0zIiwgCiAgICAgICAgICAgICAgICAgIkVwaXNjaHVyYSBsYWN1c3RyaXMiID0gInBsdW00IiwgCiAgICAgICAgICAgICAgICAgIkxpbW5vY2FsYW51cyBtYWNydXJ1cyIgPSAic2t5Ymx1ZTQiLCAKICAgICAgICAgICAgICAgICAiTGltbm9jYWxhbnVzIG1hY3J1cnVzIG1hbGUiID0gInNreWJsdWUzIiwgCiAgICAgICAgICAgICAgICAgIkxpbW5vY2FsYW51cyBtYWNydXJ1cyBqdXZlbmlsZSIgPSAic2t5Ymx1ZSIsIAogICAgICAgICAgICAgICAgICJTZW5lY2VsbGEgY2FsYW5vaWRlcyIgPSAiZGFya3NlYWdyZWVuMyIsCiAgICAgICAgICAgICAgICAgIkxlcHRvZG9yYSBraW5kdGkgbWFsZSIgPSAibGlnaHRibHVlMyIsCiAgICAgICAgICAgICAgICAgIkxlcHRvZG9yYSBraW5kdGkiID0gImxpZ2h0Ymx1ZTQiLAogICAgICAgICAgICAgICAgICJMZXB0b2RvcmEga2luZHRpIGp1dmVuaWxlIiA9ICJsaWdodGJsdWUiLAogICAgICAgICAgICAgICAgICJPc3BocmFudGljdW0gbGFicm9uZWN0dW0iID0gImxpZ2h0Y29yYWwiKQpgYGAKCiMjIENvcGVwb2QgQ29sbGVjdGlvbgoKQ29wZXBvZHMgd2VyZSBjb2xsZWN0ZWQgYXQgYXBwcm94aW1hdGVseSB3ZWVrbHkgaW50ZXJ2YWxzIGZyb20gTGFrZSBDaGFtcGxhaW4gKEJ1cmxpbmd0b24gRmlzaGluZyBQaWVyKS4gUGxhbmt0b24gd2FzIGNvbGxlY3RlZCBmcm9tIHRoZSB0b3AgMyBtZXRlcnMgdXNpbmcgYSAyNTAgdW0gbWVzaCBuZXQuIAoKYGBge3J9CiMgTGFrZSBDaGFtcGxhaW4gbmVhciBCdXJsaW5ndG9uLCBWVApzaXRlTnVtYmVyID0gIjA0Mjk0NTAwIgpDaGFtcGxhaW5JbmZvID0gcmVhZE5XSVNzaXRlKHNpdGVOdW1iZXIpCnBhcmFtZXRlckNkID0gIjAwMDEwIgpzdGFydERhdGUgPSAiMjAyMy0wMS0wMSIKZW5kRGF0ZSA9ICIiCiNzdGF0Q2QgPSBjKCIwMDAwMSIsICIwMDAwMiIsIjAwMDAzIiwgIjAwMDExIikgIyAxIC0gbWF4LCAyIC0gbWluLCAzID0gbWVhbgoKIyBDb25zdHJ1Y3RzIHRoZSBVUkwgZm9yIHRoZSBkYXRhIHdhbnRlZCB0aGVuIGRvd25sb2FkcyB0aGUgZGF0YQp1cmwgPSBjb25zdHJ1Y3ROV0lTVVJMKHNpdGVOdW1iZXJzID0gc2l0ZU51bWJlciwgcGFyYW1ldGVyQ2QgPSBwYXJhbWV0ZXJDZCwgCiAgICAgICAgICAgICAgICAgICAgICAgc3RhcnREYXRlID0gc3RhcnREYXRlLCBlbmREYXRlID0gZW5kRGF0ZSwgc2VydmljZSA9ICJ1diIpCgpyYXdfdGVtcHMgPSBpbXBvcnRXYXRlck1MMSh1cmwsIGFzRGF0ZVRpbWUgPSBUKSAlPiUgCiAgbXV0YXRlKCJkYXRlIiA9IGFzLkRhdGUoZGF0ZVRpbWUpKSAlPiUgCiAgc2VsZWN0KGRhdGVUaW1lLCB0el9jZCwgZGF0ZSwgZGVnQyA9IFhfMDAwMTBfMDAwMDApCgp0ZW1wX2RhdGEgPSAgcmF3X3RlbXBzICU+JSAKICBzZWxlY3QoZGF0ZSwgInRlbXAiID0gZGVnQykKYGBgCgpDb2xsZWN0aW9ucyBiZWdhbiBpbiBsYXRlIE1heSAyMDIzLiBTZXZlcmFsIGdhcHMgYXJlIHByZXNlbnQsIGJ1dCBjb2xsZWN0aW9ucyBoYXZlIGNvbnRpbnVlZCBhdCByb3VnaGx5IHdlZWtseSBpbnRlcnZhbHMgc2luY2UgdGhlbi4gQ29wZXBvZHMgZnJvbSBgciBsZW5ndGgodW5pcXVlKGZ1bGxfZGF0YSRjb2xsZWN0aW9uX2RhdGUpKWAgY29sbGVjdGlvbnMgd2VyZSB1c2VkIHRvIG1ha2UgYSB0b3RhbCBvZiBgciBkaW0oZnVsbF9kYXRhKVsxXWAgdGhlcm1hbCBsaW1pdCBtZWFzdXJlbWVudHMuIE92ZXIgdGhpcyB0aW1lIHBlcmlvZCwgY29sbGVjdGlvbiB0ZW1wZXJhdHVyZXMgcmFuZ2VkIGZyb20gYHIgcGFzdGUobWluKGZ1bGxfZGF0YSRjb2xsZWN0aW9uX3RlbXApLCAiIHRvICIsIG1heChmdWxsX2RhdGEkY29sbGVjdGlvbl90ZW1wKSwgc2VwID0gIiIpYMKwQy4gICAgIAoKVGhlcmUgaXMgc3Vic3RhbnRpYWwgdmFyaWF0aW9uIGluIHRoZXJtYWwgbGltaXRzIGFjcm9zcyB0aGUgc3BlY2llcyBjb2xsZWN0ZWQuIFRoZXJlIGlzIGFsc28gc29tZSBkZWdyZWUgb2YgdmFyaWF0aW9uIHdpdGhpbiB0aGUgc3BlY2llcywgd2l0aCB0aGVybWFsIGxpbWl0cyBpbmNyZWFzaW5nIHNsaWdodGx5IGR1cmluZyB0aGUgc3VtbWVyLiAgICAKCmBgYHtyIGN0bWF4LXRpbWVzZXJpZXMsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD01fQojIyBEYWlseSB2YWx1ZXMgZm9yIHRoZSBwZXJpb2QgZXhhbWluZWQgYnkgZGF0YXNldApjb2xsZWN0aW9uX2NvbmRpdGlvbnMgPSB0ZW1wX2RhdGEgJT4lCiAgdW5ncm91cCgpICU+JSAKICBncm91cF9ieShkYXRlKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fdGVtcCA9IG1lYW4odGVtcCksCiAgICAgICAgICAgIG1lZF90ZW1wID0gbWVkaWFuKHRlbXApLAogICAgICAgICAgICB2YXJfdGVtcCA9IHZhcih0ZW1wKSwgCiAgICAgICAgICAgIG1pbl90ZW1wID0gbWluKHRlbXApLCAKICAgICAgICAgICAgbWF4X3RlbXAgPSBtYXgodGVtcCkpICU+JSAKICBtdXRhdGUoInJhbmdlX3RlbXAiID0gbWF4X3RlbXAgLSBtaW5fdGVtcCwKICAgICAgICAgZGF0ZSA9IGFzLkRhdGUoZGF0ZSkpICU+JSAKICB1bmdyb3VwKCkgJT4lICAKICBmaWx0ZXIoZGF0ZSA+PSAobWluKGFzLkRhdGUoZnVsbF9kYXRhJGNvbGxlY3Rpb25fZGF0ZSkpIC0gNykpCgojIyBNZWFuIGZlbWFsZSB0aGVybWFsIGxpbWl0cyBmb3IgZWFjaCBzcGVjaWVzLCBncm91cGVkIGJ5IGNvbGxlY3Rpb24Kc3BlY2llc19zdW1tYXJpZXMgPSBmdWxsX2RhdGEgJT4lICAKICAjZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUsIGNvbGxlY3Rpb25fZGF0ZSwgY29sbGVjdGlvbl90ZW1wKSAlPiUgIAogIHN1bW1hcmlzZSgibWVhbl9jdG1heCIgPSBtZWFuKGN0bWF4KSwKICAgICAgICAgICAgInNhbXBsZV9zaXplIiA9IG4oKSwKICAgICAgICAgICAgImN0bWF4X3N0X2VyciIgPSAoc2QoY3RtYXgpIC8gc3FydChzYW1wbGVfc2l6ZSkpLAogICAgICAgICAgICAiY3RtYXhfdmFyIiA9IHZhcihjdG1heCksIAogICAgICAgICAgICAibWVhbl9zaXplIiA9IG1lYW4oc2l6ZSksCiAgICAgICAgICAgICJzaXplX3N0X2VyciIgPSAoc2Qoc2l6ZSkgLyBzcXJ0KHNhbXBsZV9zaXplKSksCiAgICAgICAgICAgICJzaXplX3ZhciIgPSB2YXIoc2l6ZSkpICU+JSAgCiAgdW5ncm91cCgpICU+JSAKICBjb21wbGV0ZShzcF9uYW1lLCBjb2xsZWN0aW9uX2RhdGUpICU+JSAKICBhcnJhbmdlKGRlc2Moc2FtcGxlX3NpemUpKQoKYWR1bHRfc3VtbWFyaWVzID0gZnVsbF9kYXRhICU+JSAgCiAgZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUsIGNvbGxlY3Rpb25fZGF0ZSwgY29sbGVjdGlvbl90ZW1wKSAlPiUgIAogIHN1bW1hcmlzZSgibWVhbl9jdG1heCIgPSBtZWFuKGN0bWF4KSwKICAgICAgICAgICAgInNhbXBsZV9zaXplIiA9IG4oKSwKICAgICAgICAgICAgImN0bWF4X3N0X2VyciIgPSAoc2QoY3RtYXgpIC8gc3FydChzYW1wbGVfc2l6ZSkpLAogICAgICAgICAgICAiY3RtYXhfdmFyIiA9IHZhcihjdG1heCksIAogICAgICAgICAgICAibWVhbl9zaXplIiA9IG1lYW4oc2l6ZSksCiAgICAgICAgICAgICJzaXplX3N0X2VyciIgPSAoc2Qoc2l6ZSkgLyBzcXJ0KHNhbXBsZV9zaXplKSksCiAgICAgICAgICAgICJzaXplX3ZhciIgPSB2YXIoc2l6ZSkpICU+JSAgCiAgdW5ncm91cCgpICU+JSAKICBjb21wbGV0ZShzcF9uYW1lLCBjb2xsZWN0aW9uX2RhdGUpICU+JSAKICBhcnJhbmdlKGRlc2Moc2FtcGxlX3NpemUpKQoKCmdncGxvdCgpICsgCiAgZ2VvbV92bGluZShkYXRhID0gdW5pcXVlKHNlbGVjdChmdWxsX2RhdGEsIGNvbGxlY3Rpb25fZGF0ZSkpLCAKICAgICAgICAgICAgIGFlcyh4aW50ZXJjZXB0ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpKSwKICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5OTAiLAogICAgICAgICAgICAgbGluZXdpZHRoID0gMSkgKyAKICBnZW9tX2xpbmUoZGF0YSA9IGNvbGxlY3Rpb25fY29uZGl0aW9ucywgCiAgICAgICAgICAgIGFlcyh4ID0gYXMuRGF0ZShkYXRlKSwgeSA9IG1lYW5fdGVtcCksCiAgICAgICAgICAgIGNvbG91ciA9ICJibGFjayIsIAogICAgICAgICAgICBsaW5ld2lkdGggPSAyKSArIAogICMgZ2VvbV9lcnJvcmJhcihkYXRhID0gc3BlY2llc19zdW1tYXJpZXMsCiAgIyAgICAgICAgICAgICAgIGFlcyh4ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpLAogICMgICAgICAgICAgICAgICAgICAgeW1pbiA9IG1lYW5fY3RtYXggLSBjdG1heF9zdF9lcnIsIHltYXggPSBtZWFuX2N0bWF4ICsgY3RtYXhfc3RfZXJyLAogICMgICAgICAgICAgICAgICAgICAgY29sb3VyID0gc3BfbmFtZSksCiAgIyAgICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAxKSwKICAjICAgICAgICAgICAgICAgd2lkdGggPSA1LCBsaW5ld2lkdGggPSAxKSArCiAgIyBnZW9tX3BvaW50KGRhdGEgPSBhZHVsdF9zdW1tYXJpZXMsIAogICMgICAgICAgICAgICBhZXMoeCA9IGFzLkRhdGUoY29sbGVjdGlvbl9kYXRlKSwgeSA9IG1lYW5fY3RtYXgsIGNvbG91ciA9IHNwX25hbWUsIHNpemUgPSBzYW1wbGVfc2l6ZSkpICsgCiAgZ2VvbV9wb2ludChkYXRhID0gZnVsbF9kYXRhLCAKICAgICAgICAgICAgIGFlcyh4ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpLCB5ID0gY3RtYXgsIGNvbG91ciA9IHNwX25hbWUpLAogICAgICAgICAgICAgc2l6ZSA9IDIsIHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyKHdpZHRoID0gMSwgaGVpZ2h0ID0gMCkpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgbGFicyh4ID0gIkRhdGUiLCAKICAgICAgIHkgPSAiVGVtcGVyYXR1cmUgKMKwQykiLCAKICAgICAgIGNvbG91ciA9ICJTcGVjaWVzIiwKICAgICAgIHNpemUgPSAiU2FtcGxlIFNpemUiKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCmBgYAoKYGBge3Igcm91bmQtc3VtbWFyeS0xLCBmaWcud2lkdGg9MTEsIGZpZy5oZWlnaHQ9MTF9CnJvdW5kX3N1bW1hcnkgPSBmdWxsX2RhdGEgJT4lIAogIGdyb3VwX2J5KGNvbGxlY3Rpb25fZGF0ZSwgY29sbGVjdGlvbl90ZW1wKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fY3RtYXggPSBtZWFuKGN0bWF4KSkKCmdncGxvdChkYXRhID0gcm91bmRfc3VtbWFyeSkgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA0MCkgKyAKICBnZW9tX3BvaW50KGFlcyh4ID0gYXNfZGF0ZShjb2xsZWN0aW9uX2RhdGUpLCB5ID0gbWVhbl9jdG1heCksCiAgICAgICAgICAgICBjb2xvdXIgPSAidG9tYXRvMyIsCiAgICAgICAgICAgICBzaXplID0gNSkgKwogIGdlb21fYmFyKGFlcyh4ID0gYXNfZGF0ZShjb2xsZWN0aW9uX2RhdGUpLCB5ID0gbWVhbl9jdG1heCksCiAgICAgICAgICAgc3RhdCA9ICJpZGVudGl0eSIsCiAgICAgICAgICAgZmlsbCA9ICJ3aGl0ZSIsIAogICAgICAgICAgIGNvbG91ciA9ICJncmV5MzAiKSArCiAgZ2VvbV9iYXIoYWVzKHggPSBhc19kYXRlKGNvbGxlY3Rpb25fZGF0ZSksIHkgPSBjb2xsZWN0aW9uX3RlbXApLAogICAgICAgICAgIHN0YXQgPSAiaWRlbnRpdHkiLAogICAgICAgICAgIGZpbGwgPSAiZGFya2dvbGRlbnJvZDEiKSArIAogIHlsaW0oLTMsIDQwKSArIAogIGNvb3JkX3BvbGFyKHN0YXJ0ID0gMCkgKyAKICB0aGVtZV92b2lkKCkKYGBgCgpgYGB7ciByb3VuZC1zdW1tYXJ5LTIsIGZpZy53aWR0aD0xMSwgZmlnLmhlaWdodD0xMX0KZ2dwbG90KCkgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAKICAgICAgICAgICAgICAgYyhtYXgoZnVsbF9kYXRhJGNvbGxlY3Rpb25fdGVtcCksCiAgICAgICAgICAgICAgICAgbWluKGZ1bGxfZGF0YSRjb2xsZWN0aW9uX3RlbXApKSwgCiAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleTYwIiwKICAgICAgICAgICAgIGxpbmV3aWR0aCA9IGMoMiwxKSwgCiAgICAgICAgICAgICBhbHBoYSA9IDAuNSkgKyAKICBnZW9tX2JhcihkYXRhID0gdW5pcXVlKHNlbGVjdChmdWxsX2RhdGEsIGNvbGxlY3Rpb25fZGF0ZSwgY29sbGVjdGlvbl90ZW1wKSksIAogICAgICAgICAgIGFlcyh4ID0gYXNfZGF0ZShjb2xsZWN0aW9uX2RhdGUpLCB5ID0gY29sbGVjdGlvbl90ZW1wKSwKICAgICAgICAgICBzdGF0ID0gImlkZW50aXR5IiwKICAgICAgICAgICBmaWxsID0gImdyZXkzMCIpICsgCiAgZ2VvbV9wb2ludChkYXRhID0gZnVsbF9kYXRhLCAKICAgICAgICAgICAgIGFlcyh4ID0gYXNfZGF0ZShjb2xsZWN0aW9uX2RhdGUpLCB5ID0gY3RtYXgpLAogICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIod2lkdGggPSAwLjcsIGhlaWdodCA9IDApLAogICAgICAgICAgICAgY29sb3VyID0gImdyZXkzMCIsCiAgICAgICAgICAgICBhbHBoYSA9IDAuNSkgKyAKICB5bGltKC0zLCA0MCkgKyAKICBjb29yZF9wb2xhcihzdGFydCA9IDApICsgCiAgdGhlbWVfdm9pZCgpCmBgYAoKClNpemUgYWxzbyB2YXJpZWQsIGJ1dCBwcmltYXJpbHkgYmV0d2VlbiByYXRoZXIgdGhhbiB3aXRoaW4gc3BlY2llcy4gCgpgYGB7ciBzaXplLXRpbWVzZXJpZXMsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD01fQpnZ3Bsb3QoKSArIAogIGdlb21fdmxpbmUoZGF0YSA9IHVuaXF1ZShzZWxlY3QoZnVsbF9kYXRhLCBjb2xsZWN0aW9uX2RhdGUpKSwgCiAgICAgICAgICAgICBhZXMoeGludGVyY2VwdCA9IGFzLkRhdGUoY29sbGVjdGlvbl9kYXRlKSksCiAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleTkwIiwKICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDEpICsgCiAgZ2VvbV9saW5lKGRhdGEgPSBjb2xsZWN0aW9uX2NvbmRpdGlvbnMsIAogICAgICAgICAgICBhZXMoeCA9IGFzLkRhdGUoZGF0ZSksIHkgPSBtZWFuX3RlbXApLAogICAgICAgICAgICBjb2xvdXIgPSAiYmxhY2siLCAKICAgICAgICAgICAgbGluZXdpZHRoID0gMikgKyAKICAjIGdlb21fZXJyb3JiYXIoZGF0YSA9IHNwZWNpZXNfc3VtbWFyaWVzLAogICMgICAgICAgICAgICAgICBhZXMoeCA9IGFzLkRhdGUoY29sbGVjdGlvbl9kYXRlKSwgCiAgIyAgICAgICAgICAgICAgICAgICB5bWluID0gbWVhbl9jdG1heCAtIGN0bWF4X3N0X2VyciwgeW1heCA9IG1lYW5fY3RtYXggKyBjdG1heF9zdF9lcnIsCiAgIyAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSBzcF9uYW1lKSwKICAjICAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDEpLAogICMgICAgICAgICAgICAgICB3aWR0aCA9IDUsIGxpbmV3aWR0aCA9IDEpICsgCiAgZ2VvbV9wb2ludChkYXRhID0gYWR1bHRfc3VtbWFyaWVzLCAKICAgICAgICAgICAgIGFlcyh4ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpLCB5ID0gbWVhbl9zaXplICogNDAsIGNvbG91ciA9IHNwX25hbWUsIHNpemUgPSBzYW1wbGVfc2l6ZSksCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMSkpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbmFtZSA9ICJUZW1wZXJhdHVyZSIsICMgRmVhdHVyZXMgb2YgdGhlIGZpcnN0IGF4aXMKICAgIHNlYy5heGlzID0gc2VjX2F4aXMofi4vNDAsIG5hbWU9IlByb3NvbWUgTGVuZ3RoIChtbSkiKSwgIyBBZGQgYSBzZWNvbmQgYXhpcyBhbmQgc3BlY2lmeSBpdHMgZmVhdHVyZXMKICAgIGJyZWFrcyA9IGMoMCw1LDEwLDE1LDIwLDI1LDMwKQogICkgKyAKICBsYWJzKHggPSAiRGF0ZSIsIAogICAgICAgeSA9ICJUZW1wZXJhdHVyZSAowrBDKSIsIAogICAgICAgY29sb3VyID0gIlNwZWNpZXMiKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCmBgYAoKU2hvd24gYmVsb3cgaXMgQ1RtYXggYW5kIGJvZHkgc2l6ZSBmb3IgdGhlIHNwZWNpZXMgd2l0aCB0aGUgbW9zdCBkYXRhICgqU2tpc3RvZGlhcHRvbXVzKiwgKkwuIG1pbnV0dXMqLCAqTC4gc2ljaWxpcyosIGFuZCAqRXBpc2NodXJhKiksIHBsb3R0ZWQgYWdhaW5zdCB0aGUgZGF5IG9mIHRoZSB5ZWFyIGZvciBlYWNoIHNleC9zdGFnZSBzZXBhcmF0ZWx5LiAKCmBgYHtyIHRyYWl0LWRveS1mZWF0dXJlLCBmaWcud2lkdGggPSAxNCwgZmlnLmhlaWdodCA9IDd9CmN0bWF4X2ZlYXR1cmUgPSBmdWxsX2RhdGEgJT4lICAKICBtdXRhdGUoZG95ID0geWRheShjb2xsZWN0aW9uX2RhdGUpKSAlPiUgCiAgZmlsdGVyKHNwX25hbWUgJWluJSBjKCJTa2lzdG9kaWFwdG9tdXMgb3JlZ29uZW5zaXMiLCAiTGVwdG9kaWFwdG9tdXMgbWludXR1cyIsICJMZXB0b2RpYXB0b211cyBzaWNpbGlzIiwgIkVwaXNjaHVyYSBsYWN1c3RyaXMiKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGFzLkRhdGUoY29sbGVjdGlvbl9kYXRlKSwgeSA9IGN0bWF4LCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBmYWNldF9ncmlkKHNwX25hbWV+c2V4KSArIAogIGdlb21fcG9pbnQoKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIGxhYnMoeCA9ICJEYXkgb2YgdGhlIFllYXIiLCAKICAgICAgIHkgPSAiQ1RtYXggKMKwQykiKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAwLCBoanVzdCA9IDAsIHZqdXN0ID0gMC41KSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCgpzaXplX2ZlYXR1cmUgPSBmdWxsX2RhdGEgJT4lICAKICBtdXRhdGUoZG95ID0geWRheShjb2xsZWN0aW9uX2RhdGUpKSAlPiUgCiAgZmlsdGVyKHNwX25hbWUgJWluJSBjKCJTa2lzdG9kaWFwdG9tdXMgb3JlZ29uZW5zaXMiLCAiTGVwdG9kaWFwdG9tdXMgbWludXR1cyIsICJMZXB0b2RpYXB0b211cyBzaWNpbGlzIiwgIkVwaXNjaHVyYSBsYWN1c3RyaXMiKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGFzLkRhdGUoY29sbGVjdGlvbl9kYXRlKSwgeSA9IHNpemUsIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGZhY2V0X2dyaWQoc3BfbmFtZX5zZXgpICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgbGFicyh4ID0gIkRheSBvZiB0aGUgWWVhciIsIAogICAgICAgeSA9ICJTaXplIChtbSkiKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAwLCBoanVzdCA9IDAsIHZqdXN0ID0gMC41KSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCgpnZ2FycmFuZ2UoY3RtYXhfZmVhdHVyZSwgc2l6ZV9mZWF0dXJlLCBjb21tb24ubGVnZW5kID0gVCwgbGVnZW5kID0gIm5vbmUiKQpgYGAKCmBgYHtyIHNwLXByb3BzLCBmaWcud2lkdGggPSAxMiwgZmlnLmhlaWdodCA9IDV9CmFkdWx0X3N1bW1hcmllcyAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBtdXRhdGUoY29sbGVjdGlvbl9udW0gPSBhcy5udW1lcmljKGZhY3Rvcihjb2xsZWN0aW9uX2RhdGUpKSkgJT4lIAogIGdyb3VwX2J5KGNvbGxlY3Rpb25fZGF0ZSkgJT4lICAKICBhcnJhbmdlKGNvbGxlY3Rpb25fZGF0ZSkgJT4lIAogIHNlbGVjdChzcF9uYW1lLCBjb2xsZWN0aW9uX2RhdGUsIGNvbGxlY3Rpb25fbnVtLCBzYW1wbGVfc2l6ZSkgJT4lIAogIG11dGF0ZShzYW1wbGVfc2l6ZSA9IHJlcGxhY2VfbmEoc2FtcGxlX3NpemUsIDApKSAlPiUgCiAgbXV0YXRlKHRvdGFsID0gc3VtKHNhbXBsZV9zaXplKSwKICAgICAgICAgcGVyY2VudGFnZSA9IHNhbXBsZV9zaXplIC8gdG90YWwsCiAgICAgICAgIGNvbGxlY3Rpb25fZGF0ZSA9IGx1YnJpZGF0ZTo6YXNfZGF0ZShjb2xsZWN0aW9uX2RhdGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gY29sbGVjdGlvbl9kYXRlLCB5ID0gcGVyY2VudGFnZSwgZmlsbCA9IHNwX25hbWUpKSArIAogIGdlb21fYXJlYSgpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKDAsMSkpICsgCiAgbGFicyh4ID0gIkNvbGxlY3Rpb24gRGF0ZSIsIAogICAgICAgeSA9ICJQcm9wb3J0aW9uIiwgCiAgICAgICBmaWxsID0gIlNwZWNpZXMiKSArIAogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMjApICsgCiAgdGhlbWUocGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9saW5lKCkpCmBgYAoKCmBgYHtyIHBhdGhvZ2VuLXByb3BzfQpwYXRob2dlbl9jb2xzID0gYygibm8iID0gImdyZXk5NSIsICJjbG91ZHkiID0gImhvbmV5ZGV3MyIsICJzcG90IiA9ICJhbnRpcXVld2hpdGUzIiwgIm90aGVyIiA9ICJ0b21hdG8zIikKCmZ1bGxfZGF0YSAlPiUgCiAgc2VsZWN0KGNvbGxlY3Rpb25fZGF0ZSwgZGV2X2VnZ3MsIHBhdGhvZ2VuLCBsaXBpZHMsIHNwX25hbWUsIHNleCkgJT4lIAogIGdyb3VwX2J5KCkgJT4lIAogIGZpbHRlcihzZXggIT0gImp1dmVuaWxlIikgJT4lIAogIGdyb3VwX2J5KGNvbGxlY3Rpb25fZGF0ZSkgJT4lIAogIGNvdW50KHBhdGhvZ2VuKSAlPiUgCiAgZmlsdGVyKHBhdGhvZ2VuICE9ICJ1bmNlcnRhaW4iKSAlPiUgCiAgcGl2b3Rfd2lkZXIoaWRfY29scyA9ICJjb2xsZWN0aW9uX2RhdGUiLCAKICAgICAgICAgICAgICBuYW1lc19mcm9tID0gcGF0aG9nZW4sIAogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gbiwKICAgICAgICAgICAgICB2YWx1ZXNfZmlsbCA9IDApICU+JSAKICBtdXRhdGUodG90YWwgPSBzdW0obm8sIGNsb3VkeSwgc3BvdCwgb3RoZXIpKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKG5vLCBjbG91ZHksIHNwb3QsIG90aGVyKSwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicGF0aG9nZW4iLCAKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gImNvdW50IikgJT4lIAogIG11dGF0ZShwZXJjZW50ID0gY291bnQvdG90YWwsCiAgICAgICAgIGNvbGxlY3Rpb25fZGF0ZSA9IGx1YnJpZGF0ZTo6YXNfZGF0ZShjb2xsZWN0aW9uX2RhdGUpLAogICAgICAgICBwYXRob2dlbiA9IGZjdF9yZWxldmVsKHBhdGhvZ2VuLCAibm8iLCAiY2xvdWR5IiwgInNwb3QiLCAib3RoZXIiKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGNvbGxlY3Rpb25fZGF0ZSwgeSA9IHBlcmNlbnQsIGZpbGwgPSBwYXRob2dlbikpICsgCiAgZ2VvbV9hcmVhKCkgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBwYXRob2dlbl9jb2xzKSArIAogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKDAsMSkpICsgCiAgbGFicyh4ID0gIkNvbGxlY3Rpb24gRGF0ZSIsIAogICAgICAgeSA9ICJQcm9wb3J0aW9uIiwgCiAgICAgICBmaWxsID0gIlBhdGhvZ2VuIikgKyAKICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDIwKSArIAogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfbGluZSgpKQpgYGAKCgpgYGB7ciBkZXZlZ2dzLXByb3BzLCBmaWcuaGVpZ2h0ID0gMTIsIGZpZy53aWR0aCA9IDh9CmRldl9lZ2dzX2NvbHMgPSBjKCJubyIgPSAiZ3JleTk1IiwgInllcyIgPSAibGlnaHRibHVlMyIpCgpmdWxsX2RhdGEgJT4lIAogIHNlbGVjdChjb2xsZWN0aW9uX2RhdGUsIGRldl9lZ2dzLCBwYXRob2dlbiwgbGlwaWRzLCBzcF9uYW1lLCBzZXgpICU+JSAKICBncm91cF9ieShzcF9uYW1lKSAlPiUgCiAgZmlsdGVyKHNleCAhPSAianV2ZW5pbGUiKSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSwgY29sbGVjdGlvbl9kYXRlKSAlPiUgCiAgY291bnQoZGV2X2VnZ3MpICU+JSAKICBmaWx0ZXIoZGV2X2VnZ3MgIT0gInVuY2VydGFpbiIpICU+JSAKICBwaXZvdF93aWRlcihpZF9jb2xzID0gYygiY29sbGVjdGlvbl9kYXRlIiwgInNwX25hbWUiKSwgCiAgICAgICAgICAgICAgbmFtZXNfZnJvbSA9IGRldl9lZ2dzLCAKICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IG4sCiAgICAgICAgICAgICAgdmFsdWVzX2ZpbGwgPSAwKSAlPiUgCiAgbXV0YXRlKHRvdGFsID0gc3VtKG5vLCB5ZXMpKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKG5vLCB5ZXMpLAogICAgICAgICAgICAgICBuYW1lc190byA9ICJkZXZfZWdncyIsIAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUgCiAgbXV0YXRlKHBlcmNlbnQgPSBjb3VudC90b3RhbCwKICAgICAgICAgY29sbGVjdGlvbl9kYXRlID0gbHVicmlkYXRlOjphc19kYXRlKGNvbGxlY3Rpb25fZGF0ZSksCiAgICAgICAgIGRldl9lZ2dzID0gZmN0X3JlbGV2ZWwoZGV2X2VnZ3MsICJubyIsICJ5ZXMiKSkgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgY29tcGxldGUoY29sbGVjdGlvbl9kYXRlLCBuZXN0aW5nKHNwX25hbWUsIGRldl9lZ2dzKSwgZmlsbCA9IGxpc3QocGVyY2VudCA9IDEpKSAlPiUgCiAgbXV0YXRlKHBlcmNlbnQgPSBpZl9lbHNlKGlzLm5hKHRvdGFsKSAmIGRldl9lZ2dzID09ICJ5ZXMiLCAwLCBwZXJjZW50KSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGNvbGxlY3Rpb25fZGF0ZSwgeSA9IHBlcmNlbnQsIGZpbGwgPSBkZXZfZWdncykpICsgCiAgZmFjZXRfd3JhcChzcF9uYW1lfi4sIG5jb2wgPSAxKSArIAogIGdlb21fYXJlYSgpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gZGV2X2VnZ3NfY29scykgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygwLDEpKSArIAogIGxhYnMoeCA9ICJDb2xsZWN0aW9uIERhdGUiLCAKICAgICAgIHkgPSAiUHJvcG9ydGlvbiIsIAogICAgICAgZmlsbCA9ICJEZXZlbG9waW5nIFxuRWdncyIpICsgCiAgdGhlbWVfbWluaW1hbChiYXNlX3NpemUgPSAyMCkgKyAKICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2xpbmUoKSkKYGBgCgoKYGBge3IgbGlwaWRzLXByb3BzLCBmaWcuaGVpZ2h0ID0gMTIsIGZpZy53aWR0aCA9IDh9CmxpcGlkX2NvbHMgPSBjKCJubyIgPSAiZ3JleTk1IiwgInllcyIgPSAic2llbm5hMiIpCgpmdWxsX2RhdGEgJT4lIAogIHNlbGVjdChjb2xsZWN0aW9uX2RhdGUsIGRldl9lZ2dzLCBwYXRob2dlbiwgbGlwaWRzLCBzcF9uYW1lLCBzZXgpICU+JSAKICBncm91cF9ieShzcF9uYW1lKSAlPiUgCiAgZmlsdGVyKHNleCAhPSAianV2ZW5pbGUiKSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSwgY29sbGVjdGlvbl9kYXRlKSAlPiUgCiAgY291bnQobGlwaWRzKSAlPiUgCiAgZmlsdGVyKGxpcGlkcyAhPSAidW5jZXJ0YWluIikgJT4lIAogIHBpdm90X3dpZGVyKGlkX2NvbHMgPSBjKCJjb2xsZWN0aW9uX2RhdGUiLCAic3BfbmFtZSIpLCAKICAgICAgICAgICAgICBuYW1lc19mcm9tID0gbGlwaWRzLCAKICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IG4sCiAgICAgICAgICAgICAgdmFsdWVzX2ZpbGwgPSAwKSAlPiUgCiAgbXV0YXRlKHRvdGFsID0gc3VtKG5vLCB5ZXMpKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKG5vLCB5ZXMpLAogICAgICAgICAgICAgICBuYW1lc190byA9ICJsaXBpZHMiLCAKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gImNvdW50IikgJT4lIAogIG11dGF0ZShwZXJjZW50ID0gY291bnQvdG90YWwsCiAgICAgICAgIGNvbGxlY3Rpb25fZGF0ZSA9IGx1YnJpZGF0ZTo6YXNfZGF0ZShjb2xsZWN0aW9uX2RhdGUpLAogICAgICAgICBsaXBpZHMgPSBmY3RfcmVsZXZlbChsaXBpZHMsICJubyIsICJ5ZXMiKSkgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgY29tcGxldGUoY29sbGVjdGlvbl9kYXRlLCBuZXN0aW5nKHNwX25hbWUsIGxpcGlkcyksIGZpbGwgPSBsaXN0KHBlcmNlbnQgPSAxKSkgJT4lIAogIG11dGF0ZShwZXJjZW50ID0gaWZfZWxzZShpcy5uYSh0b3RhbCkgJiBsaXBpZHMgPT0gInllcyIsIDAsIHBlcmNlbnQpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gY29sbGVjdGlvbl9kYXRlLCB5ID0gcGVyY2VudCwgZmlsbCA9IGxpcGlkcykpICsgCiAgZmFjZXRfd3JhcChzcF9uYW1lfi4sIG5jb2wgPSAxKSArIAogIGdlb21fYXJlYSgpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbGlwaWRfY29scykgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygwLDEpKSArIAogIGxhYnMoeCA9ICJDb2xsZWN0aW9uIERhdGUiLCAKICAgICAgIHkgPSAiUHJvcG9ydGlvbiIsIAogICAgICAgZmlsbCA9ICJMaXBpZHNcblByZXNlbnQiKSArIAogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMjApICsgCiAgdGhlbWUocGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9saW5lKCkpCmBgYAoKCiMjIFRlbXBlcmF0dXJlIFZhcmlhYmlsaXR5Ckxha2UgQ2hhbXBsYWluIGlzIGhpZ2hseSBzZWFzb25hbCwgd2l0aCBib3RoIGF2ZXJhZ2UgdGVtcGVyYXR1cmVzIGFuZCB0ZW1wZXJhdHVyZSB2YXJpYWJpbGl0eSBjaGFuZ2luZyB0aHJvdWdob3V0IHRoZSB5ZWFyLiBUaGVzZSBwYXR0ZXJucyBpbiB0aGUgZXhwZXJpZW5jZWQgdGhlcm1hbCBlbnZpcm9ubWVudCBtYXkgZHJpdmUgdGhlIG9ic2VydmVkIHZhcmlhdGlvbiBpbiBjb3BlcG9kIHRoZXJtYWwgbGltaXRzLiBIb3dldmVyLCB0aGUgdGltZSBwZXJpb2QgYWZmZWN0aW5nIGNvcGVwb2QgdGhlcm1hbCBsaW1pdHMgaXMgdW5rbm93bi4gRGVwZW5kaW5nIHRoZSBvbiB0aGUgZHVyYXRpb24gb2YgdGltZSBjb25zaWRlcmVkLCB0aGVyZSBhcmUgbGFyZ2UgY2hhbmdlcyBpbiB0aGUgZXhwZXJpZW5jZWQgZW52aXJvbm1lbnQsIGluIHBhcnRpY3VsYXIgcmVnYXJkaW5nIHRoZSB0ZW1wZXJhdHVyZSByYW5nZSBhbmQgdmFyaWFuY2UuIENvbnNpZGVyIGZvciBleGFtcGxlIHRocmVlIHRpbWUgcGVyaW9kczogdGhlIGRheSBvZiBjb2xsZWN0aW9uLCBvbmUgd2VlayBwcmlvciB0byBjb2xsZWN0aW9uLCBhbmQgZm91ciB3ZWVrcyBwcmlvciB0byBjb2xsZWN0aW9uLiBXaGlsZSB0aGUgb3ZlcmFsbCBwYXR0ZXJuIGlzIHNpbWlsYXIsIHdlIGNhbiBzZWUgdGhhdCwgdW5zdXJwcmlzaW5nbHksIGNvbnNpZGVyaW5nIGxvbmdlciBwZXJpb2RzIG9mIHRpbWUgcmVzdWx0cyBpbiBsYXJnZXIgcmFuZ2VzIGFuZCBzbGlnaHRseSBjaGFuZ2VzIHRoZSBwYXR0ZXJuIG9mIHZhcmlhbmNlIGV4cGVyaWVuY2VkLiAKCmBgYHtyIGRhaWx5LXRlbXAtZGF0YX0KIyMgRGFpbHkgdmFsdWVzCmRhaWx5X3RlbXBfZGF0YSA9IHRlbXBfZGF0YSAlPiUKICB1bmdyb3VwKCkgJT4lIAogIGdyb3VwX2J5KGRhdGUpICU+JSAKICBzdW1tYXJpc2UobWVhbl90ZW1wID0gbWVhbih0ZW1wKSwKICAgICAgICAgICAgbWVkX3RlbXAgPSBtZWRpYW4odGVtcCksCiAgICAgICAgICAgIHZhcl90ZW1wID0gdmFyKHRlbXApLCAKICAgICAgICAgICAgbWluX3RlbXAgPSBtaW4odGVtcCksIAogICAgICAgICAgICBtYXhfdGVtcCA9IG1heCh0ZW1wKSkgJT4lIAogIG11dGF0ZSgicmFuZ2VfdGVtcCIgPSBtYXhfdGVtcCAtIG1pbl90ZW1wKQoKZGF5X3ByaW9yX3RlbXBfZGF0YSA9IHRlbXBfZGF0YSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBncm91cF9ieShkYXRlKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fdGVtcCA9IG1lYW4odGVtcCksCiAgICAgICAgICAgIG1lZF90ZW1wID0gbWVkaWFuKHRlbXApLAogICAgICAgICAgICB2YXJfdGVtcCA9IHZhcih0ZW1wKSwgCiAgICAgICAgICAgIG1pbl90ZW1wID0gbWluKHRlbXApLCAKICAgICAgICAgICAgbWF4X3RlbXAgPSBtYXgodGVtcCkpICU+JSAKICBtdXRhdGUoZGF0ZSA9IGRhdGUgKyAxKSAlPiUgCiAgcmVuYW1lX3dpdGgoLmZuID0gfiBwYXN0ZTAoInByaW9yX2RheV8iLCAueCksIC5jb2xzID0gYygtZGF0ZSkpCgpkYWlseV9wbG90ID0gZGFpbHlfdGVtcF9kYXRhICU+JSAKICBwaXZvdF9sb25nZXIoY29scyA9IGMoLWRhdGUpLAogICAgICAgICAgICAgICBuYW1lc190byA9ICJwYXJhbWV0ZXIiLCAKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInRlbXAiKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gZGF0ZSwgeSA9IHRlbXAsIGNvbG91ciA9IHBhcmFtZXRlcikpICsgCiAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDEpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKAogICAgIm1lYW5fdGVtcCIgPSAib2xpdmVkcmFiMyIsCiAgICAibWVkX3RlbXAiID0gInNlYWdyZWVuMyIsCiAgICAibWF4X3RlbXAiID0gInRvbWF0byIsICAKICAgICJtaW5fdGVtcCIgPSAiZG9kZ2VyYmx1ZSIsCiAgICAicmFuZ2VfdGVtcCIgPSAiZ29sZGVucm9kMyIsCiAgICAidmFyX3RlbXAiID0gImRhcmtnb2xkZW5yb2QxIgogICkpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGFzLkRhdGUoYygiMjAyMy0wMS0wMSIsICIyMDIzLTA0LTAxIiwgIjIwMjMtMDctMDEiKSkpICsgCiAgZ2d0aXRsZSgiRGFpbHkgVmFsdWVzIikgKyAKICBsYWJzKHkgPSAiVGVtcGVyYXR1cmUgKMKwQykiLAogICAgICAgeCA9ICIiKSArIAogIHRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDIwKSArIAogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAyNzAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpKQpgYGAKCmBgYHtyIHByZWRpY3RvcnMtZnVuY3Rpb259CiMjIERlZmluaW5nIHRoZSBmdW5jdGlvbiB0byBnZXQgcHJlZGljdG9yIHZhbHVlcyBmb3IgcGVyaW9kcyBvZiBkaWZmZXJlbnQgbGVuZ3RocwpnZXRfcHJlZGljdG9ycyA9IGZ1bmN0aW9uKGRhaWx5X3ZhbHVlcywgcmF3X3RlbXAsIG5fZGF5cyl7CiAgcHJlZml4ID0gc3RyX3JlcGxhY2VfYWxsKHhmdW46Om51bWJlcnNfdG9fd29yZHMobl9kYXlzKSwgcGF0dGVybiA9ICIgIiwgcmVwbGFjZW1lbnQgPSAiLSIpCiAgCiAgbWVhbl92YWx1ZXMgPSBkYWlseV92YWx1ZXMgJT4lIAogICAgdW5ncm91cCgpICU+JSAKICAgIG11dGF0ZShtZWFuX21heCA9IHNsaWRlX3ZlYygueCA9IG1heF90ZW1wLCAuZiA9IG1lYW4sIC5iZWZvcmUgPSBuX2RheXMsIC5jb21wbGV0ZSA9IFQpLAogICAgICAgICAgIG1lYW5fbWluID0gc2xpZGVfdmVjKC54ID0gbWluX3RlbXAsIC5mID0gbWVhbiwgLmJlZm9yZSA9IG5fZGF5cywgLmNvbXBsZXRlID0gVCksCiAgICAgICAgICAgbWVhbl9yYW5nZSA9IHNsaWRlX3ZlYygueCA9IHJhbmdlX3RlbXAsIC5mID0gbWVhbiwgLmJlZm9yZSA9IG5fZGF5cywgLmNvbXBsZXRlID0gVCkpICU+JSAKICAgIHNlbGVjdChkYXRlLCBtZWFuX21heCwgbWVhbl9taW4sIG1lYW5fcmFuZ2UpICU+JSAKICAgIHJlbmFtZV93aXRoKCB+IHBhc3RlKHByZWZpeCwgImRheSIsIC54LCBzZXAgPSAiXyIpLCAuY29scyA9IGMoLWRhdGUpKQogIAogIHBlcmlvZF92YWx1ZXMgPSByYXdfdGVtcCAlPiUgCiAgICBtdXRhdGUobWVhbiA9IHNsaWRlX2luZGV4X21lYW4odGVtcCwgaSA9IGRhdGUsIGJlZm9yZSA9IGRheXMobl9kYXlzKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFfcm0gPSBUKSwKICAgICAgICAgICBtYXggPSBzbGlkZV9pbmRleF9tYXgodGVtcCwgaSA9IGRhdGUsIGJlZm9yZSA9IGRheXMobl9kYXlzKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hX3JtID0gVCksCiAgICAgICAgICAgbWluID0gc2xpZGVfaW5kZXhfbWluKHRlbXAsIGkgPSBkYXRlLCBiZWZvcmUgPSBkYXlzKG5fZGF5cyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hX3JtID0gVCksCiAgICAgICAgICAgbWVkID0gc2xpZGVfaW5kZXhfZGJsKHRlbXAsIC5pID0gZGF0ZSwgLmJlZm9yZSA9IGRheXMobl9kYXlzKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hX3JtID0gVCwgLmYgPSBtZWRpYW4pLAogICAgICAgICAgIHZhciA9IHNsaWRlX2luZGV4X2RibCh0ZW1wLCAuaSA9IGRhdGUsIC5iZWZvcmUgPSBkYXlzKG5fZGF5cyksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZiA9IHZhciksCiAgICAgICAgICAgcmFuZ2UgPSBtYXggLSBtaW4pICU+JSAgCiAgICBzZWxlY3QoLXRlbXApICU+JSAgCiAgICBkaXN0aW5jdCgpICU+JSAKICAgIHJlbmFtZV93aXRoKCB+IHBhc3RlKHByZWZpeCwgImRheSIsIC54LCBzZXAgPSAiXyIpLCAuY29scyA9IGMoLWRhdGUpKSU+JSAKICAgIGlubmVyX2pvaW4obWVhbl92YWx1ZXMsIGJ5ID0gYygiZGF0ZSIpKSAlPiUgIAogICAgZHJvcF9uYSgpCiAgCiAgcmV0dXJuKHBlcmlvZF92YWx1ZXMpCn0KYGBgCgpgYGB7ciBwcmVkaWN0b3JzLWFuZC1wbG90cywgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTV9CiMgIyMgR2V0dGluZyBwcmVkaWN0b3IgdmFyaWFibGVzIGZvciBkaWZmZXJlbnQgcGVyaW9kcwojIAojICMjIyBTaG9ydCAodGhyZWUgZGF5cykKIyB0aHJlZV9kYXlfdGVtcHMgPSBnZXRfcHJlZGljdG9ycyhkYWlseV92YWx1ZXMgPSBkYWlseV90ZW1wX2RhdGEsIAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhd190ZW1wID0gdGVtcF9kYXRhLCAKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuX2RheXMgPSAzKQojIAojICMjIyBPTkUgV0VFSwp3ZWVrX3RlbXBzID0gZ2V0X3ByZWRpY3RvcnMoZGFpbHlfdmFsdWVzID0gZGFpbHlfdGVtcF9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmF3X3RlbXAgPSB0ZW1wX2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuX2RheXMgPSA3KQoKd2Vla19wbG90ID0gd2Vla190ZW1wcyAlPiUKICBwaXZvdF9sb25nZXIoY29scyA9IGMoLWRhdGUpLAogICAgICAgICAgICAgICBuYW1lc190byA9ICJwYXJhbWV0ZXIiLAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAidGVtcCIpICU+JQogIGZpbHRlcihwYXJhbWV0ZXIgJWluJSBjKCJzZXZlbl9kYXlfbWVhbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInNldmVuX2RheV9tZWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJzZXZlbl9kYXlfbWF4IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAic2V2ZW5fZGF5X21pbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInNldmVuX2RheV92YXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJzZXZlbl9kYXlfcmFuZ2UiKSkgJT4lCiAgbXV0YXRlKHBhcmFtZXRlciA9IHBhc3RlKHdvcmQocGFyYW1ldGVyLCBzdGFydCA9IDMsIHNlcCA9IGZpeGVkKCJfIikpLCAiX3RlbXAiLCBzZXAgPSAiIikpICU+JQogIGdncGxvdChhZXMoeCA9IGRhdGUsIHkgPSB0ZW1wLCBjb2xvdXIgPSBwYXJhbWV0ZXIpKSArCiAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDEpICsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoCiAgICAibWVhbl90ZW1wIiA9ICJvbGl2ZWRyYWIzIiwKICAgICJtZWRfdGVtcCIgPSAic2VhZ3JlZW4zIiwKICAgICJtYXhfdGVtcCIgPSAidG9tYXRvIiwKICAgICJtaW5fdGVtcCIgPSAiZG9kZ2VyYmx1ZSIsCiAgICAicmFuZ2VfdGVtcCIgPSAiZ29sZGVucm9kMyIsCiAgICAidmFyX3RlbXAiID0gImRhcmtnb2xkZW5yb2QxIgogICkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYXMuRGF0ZShjKCIyMDIzLTAxLTAxIiwgIjIwMjMtMDQtMDEiLCAiMjAyMy0wNy0wMSIpKSkgKwogIGdndGl0bGUoIk9uZSBXZWVrIikgKwogIGxhYnMoeSA9ICJUZW1wZXJhdHVyZSAowrBDKSIsCiAgICAgICB4ID0gIiIpICsKICB0aGVtZV9idyhiYXNlX3NpemUgPSAyMCkgKwogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAyNzAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpKQojIAojIAojICMjIyBUV08gV0VFS1MKIyB0d29fd2Vla190ZW1wcyA9IGdldF9wcmVkaWN0b3JzKGRhaWx5X3ZhbHVlcyA9IGRhaWx5X3RlbXBfZGF0YSwgCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXdfdGVtcCA9IHRlbXBfZGF0YSwgCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuX2RheXMgPSAxNCkKIyAKIyB0d29fd2Vla19wbG90ID0gdHdvX3dlZWtfdGVtcHMgJT4lIAojICAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKC1kYXRlKSwKIyAgICAgICAgICAgICAgICBuYW1lc190byA9ICJwYXJhbWV0ZXIiLCAKIyAgICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAidGVtcCIpICU+JSAKIyAgIGZpbHRlcihwYXJhbWV0ZXIgJWluJSBjKCJmb3VydGVlbl9kYXlfbWVhbiIsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAiZm91cnRlZW5fZGF5X21lZCIsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAiZm91cnRlZW5fZGF5X21heCIsIAojICAgICAgICAgICAgICAgICAgICAgICAgICAgImZvdXJ0ZWVuX2RheV9taW4iLCAKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICJmb3VydGVlbl9kYXlfdmFyIiwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICJmb3VydGVlbl9kYXlfcmFuZ2UiKSkgJT4lIAojICAgbXV0YXRlKHBhcmFtZXRlciA9IHBhc3RlKHdvcmQocGFyYW1ldGVyLCBzdGFydCA9IDMsIHNlcCA9IGZpeGVkKCJfIikpLCAiX3RlbXAiLCBzZXAgPSAiIikpICU+JSAKIyAgIGdncGxvdChhZXMoeCA9IGRhdGUsIHkgPSB0ZW1wLCBjb2xvdXIgPSBwYXJhbWV0ZXIpKSArIAojICAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDEpICsgCiMgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoCiMgICAgICJtZWFuX3RlbXAiID0gIm9saXZlZHJhYjMiLAojICAgICAibWVkX3RlbXAiID0gInNlYWdyZWVuMyIsCiMgICAgICJtYXhfdGVtcCIgPSAidG9tYXRvIiwgIAojICAgICAibWluX3RlbXAiID0gImRvZGdlcmJsdWUiLAojICAgICAicmFuZ2VfdGVtcCIgPSAiZ29sZGVucm9kMyIsCiMgICAgICJ2YXJfdGVtcCIgPSAiZGFya2dvbGRlbnJvZDEiCiMgICApKSArIAojICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGFzLkRhdGUoYygiMjAyMy0wMS0wMSIsICIyMDIzLTA0LTAxIiwgIjIwMjMtMDctMDEiKSkpICsgCiMgICBnZ3RpdGxlKCJUd28gV2Vla3MiKSArIAojICAgbGFicyh5ID0gIlRlbXBlcmF0dXJlICjCsEMpIiwKIyAgICAgICAgeCA9ICIiKSArIAojICAgdGhlbWVfYncoYmFzZV9zaXplID0gMjApICsgCiMgICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLAojICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAyNzAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpKQojIAojIAojICMjIyBGT1VSIFdFRUtTCmZvdXJfd2Vla190ZW1wcyA9IGdldF9wcmVkaWN0b3JzKGRhaWx5X3ZhbHVlcyA9IGRhaWx5X3RlbXBfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmF3X3RlbXAgPSB0ZW1wX2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5fZGF5cyA9IDI4KQoKZm91cl93ZWVrX3Bsb3QgPSBmb3VyX3dlZWtfdGVtcHMgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKC1kYXRlKSwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicGFyYW1ldGVyIiwKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInRlbXAiKSAlPiUKICBmaWx0ZXIocGFyYW1ldGVyICVpbiUgYygidHdlbnR5LWVpZ2h0X2RheV9tZWFuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAidHdlbnR5LWVpZ2h0X2RheV9tZWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJ0d2VudHktZWlnaHRfZGF5X21heCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInR3ZW50eS1laWdodF9kYXlfbWluIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAidHdlbnR5LWVpZ2h0X2RheV92YXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJ0d2VudHktZWlnaHRfZGF5X3JhbmdlIikpICU+JQogIG11dGF0ZShwYXJhbWV0ZXIgPSBwYXN0ZSh3b3JkKHBhcmFtZXRlciwgc3RhcnQgPSAzLCBzZXAgPSBmaXhlZCgiXyIpKSwgIl90ZW1wIiwgc2VwID0gIiIpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBkYXRlLCB5ID0gdGVtcCwgY29sb3VyID0gcGFyYW1ldGVyKSkgKwogIGdlb21fbGluZShsaW5ld2lkdGggPSAxKSArCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKAogICAgIm1lYW5fdGVtcCIgPSAib2xpdmVkcmFiMyIsCiAgICAibWVkX3RlbXAiID0gInNlYWdyZWVuMyIsCiAgICAibWF4X3RlbXAiID0gInRvbWF0byIsCiAgICAibWluX3RlbXAiID0gImRvZGdlcmJsdWUiLAogICAgInJhbmdlX3RlbXAiID0gImdvbGRlbnJvZDMiLAogICAgInZhcl90ZW1wIiA9ICJkYXJrZ29sZGVucm9kMSIKICApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGFzLkRhdGUoYygiMjAyMy0wMS0wMSIsICIyMDIzLTA0LTAxIiwgIjIwMjMtMDctMDEiKSkpICsKICBnZ3RpdGxlKCJGb3VyIFdlZWtzIikgKwogIGxhYnMoeSA9ICJUZW1wZXJhdHVyZSAowrBDKSIsCiAgICAgICB4ID0gIiIpICsKICB0aGVtZV9idyhiYXNlX3NpemUgPSAyMCkgKwogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAyNzAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpKQojIAojIAojICMjIyBFSUdIVCBXRUVLUwojIGVpZ2h0X3dlZWtfdGVtcHMgPSBnZXRfcHJlZGljdG9ycyhkYWlseV92YWx1ZXMgPSBkYWlseV90ZW1wX2RhdGEsIAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXdfdGVtcCA9IHRlbXBfZGF0YSwgCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5fZGF5cyA9IDU2KQojIAojIGVpZ2h0X3dlZWtfcGxvdCA9IGVpZ2h0X3dlZWtfdGVtcHMgJT4lIAojICAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKC1kYXRlKSwKIyAgICAgICAgICAgICAgICBuYW1lc190byA9ICJwYXJhbWV0ZXIiLCAKIyAgICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAidGVtcCIpICU+JSAKIyAgIGZpbHRlcihwYXJhbWV0ZXIgJWluJSBjKCJmaWZ0eS1zaXhfZGF5X21lYW4iLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgImZpZnR5LXNpeF9kYXlfbWVkIiwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICJmaWZ0eS1zaXhfZGF5X21heCIsIAojICAgICAgICAgICAgICAgICAgICAgICAgICAgImZpZnR5LXNpeF9kYXlfbWluIiwgCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmlmdHktc2l4X2RheV92YXIiLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgImZpZnR5LXNpeF9kYXlfcmFuZ2UiKSkgJT4lIAojICAgbXV0YXRlKHBhcmFtZXRlciA9IHBhc3RlKHdvcmQocGFyYW1ldGVyLCBzdGFydCA9IDMsIHNlcCA9IGZpeGVkKCJfIikpLCAiX3RlbXAiLCBzZXAgPSAiIikpICU+JSAKIyAgIGdncGxvdChhZXMoeCA9IGRhdGUsIHkgPSB0ZW1wLCBjb2xvdXIgPSBwYXJhbWV0ZXIpKSArIAojICAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDEpICsgCiMgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoCiMgICAgICJtZWFuX3RlbXAiID0gIm9saXZlZHJhYjMiLAojICAgICAibWVkX3RlbXAiID0gInNlYWdyZWVuMyIsCiMgICAgICJtYXhfdGVtcCIgPSAidG9tYXRvIiwgIAojICAgICAibWluX3RlbXAiID0gImRvZGdlcmJsdWUiLAojICAgICAicmFuZ2VfdGVtcCIgPSAiZ29sZGVucm9kMyIsCiMgICAgICJ2YXJfdGVtcCIgPSAiZGFya2dvbGRlbnJvZDEiCiMgICApKSArIAojICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGFzLkRhdGUoYygiMjAyMy0wMS0wMSIsICIyMDIzLTA0LTAxIiwgIjIwMjMtMDctMDEiKSkpICsgCiMgICBnZ3RpdGxlKCJFaWdodCBXZWVrcyIpICsgCiMgICBsYWJzKHkgPSAiVGVtcGVyYXR1cmUgKMKwQykiLAojICAgICAgICB4ID0gIiIpICsgCiMgICB0aGVtZV9idyhiYXNlX3NpemUgPSAyMCkgKyAKIyAgIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiMgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDI3MCwgaGp1c3QgPSAwLCB2anVzdCA9IDAuNSkpCiMgCmdnYXJyYW5nZShkYWlseV9wbG90LCB3ZWVrX3Bsb3QsIGZvdXJfd2Vla19wbG90LCAKICAgICAgICAgIGNvbW1vbi5sZWdlbmQgPSBULCBucm93ID0gMSwgbGVnZW5kID0gImJvdHRvbSIpCmBgYAoKVGhlIGRpZmZlcmVudCB0aW1lIHBlcmlvZHMgZXhhbWluZWQgYnkgdGhpcyBjbGltYXRlIGRhdGEgaGlnaGxpZ2h0cyB0aGF0IHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBtaW5pbXVtIGFuZCBtYXhpbXVtIHRlbXBlcmF0dXJlcyBjaGFuZ2VzIGJhc2VkIG9uIHRoZSB3aW5kb3cgZXhhbWluZWQuIEZvciBleGFtcGxlLCBtaW5pbXVtIGFuZCBtYXhpbXVtIHRlbXBlcmF0dXJlcyBleHBlcmllbmNlZCBvdmVyIHdlZWtseSBpbnRlcnZhbHMgYXJlIGNsb3NlbHkgbGlua2VkLCB3aGVyZWFzIHRoZXJlIGlzIGEgZGlzdGluY3Qgc2Vhc29uYWwgY3ljbGUgaW4gdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIG1pbmltdW0gYW5kIG1heGltdW0gdGVtcGVyYXR1cmVzIGV4cGVyaWVuY2VkIG92ZXIgcGVyaW9kcyBvZiBmb3VyIHdlZWtzLiAKCmBgYHtyfQpvbmVfd2Vla19kb3lfZGF0YSA9IHdlZWtfdGVtcHMgJT4lIAogIG11dGF0ZShkb3kgPSB5ZGF5KGRhdGUpKQoKb25lX3dlZWtfdGVtcF9jaXJjbGUgPSBnZ3Bsb3Qob25lX3dlZWtfZG95X2RhdGEsIGFlcyh4ID0gc2V2ZW5fZGF5X21lYW5fbWF4LCB5ID0gc2V2ZW5fZGF5X21lYW5fbWluLCBjb2xvdXIgPSBkb3kpKSArIAogIGdlb21fcG9pbnQoKSArIAogIHNjYWxlX2NvbG91cl9ncmFkaWVudDIoCiAgICBoaWdoID0gImRvZGdlcmJsdWU0IiwKICAgIG1pZCA9ICJjb3JhbDIiLAogICAgbG93ID0gImRvZGdlcmJsdWU0IiwKICAgIG1pZHBvaW50ID0gMTgyLjUpICsgCiAgbGFicyh4ID0gIk1heC4gVGVtcC4gKMKwQykiLAogICAgICAgeSA9ICJNaW4uIFRlbXAuICjCsEMpIikgKyAKICBsYWJzKHggPSAiTWF4LiBUZW1wLiAowrBDKSIsCiAgICAgICB5ID0gIk1pbi4gVGVtcC4gKMKwQykiKSArIAogIGdndGl0bGUoIk9uZSBXZWVrIikgKyAKICB0aGVtZV9tYXR0KCkKCmZvdXJfd2Vla19kb3lfZGF0YSA9IGZvdXJfd2Vla190ZW1wcyAlPiUgCiAgbXV0YXRlKGRveSA9IHlkYXkoZGF0ZSkpCgpmb3VyX3dlZWtfdGVtcF9jaXJjbGUgPSBnZ3Bsb3QoZm91cl93ZWVrX2RveV9kYXRhLCBhZXMoeCA9IGB0d2VudHktZWlnaHRfZGF5X21heGAsIHkgPSBgdHdlbnR5LWVpZ2h0X2RheV9taW5gLCBjb2xvdXIgPSBkb3kpKSArIAogIGdlb21fcG9pbnQoKSArIAogIHNjYWxlX2NvbG91cl9ncmFkaWVudDIoCiAgICBoaWdoID0gImRvZGdlcmJsdWU0IiwKICAgIG1pZCA9ICJjb3JhbDIiLAogICAgbG93ID0gImRvZGdlcmJsdWU0IiwKICAgIG1pZHBvaW50ID0gMTgyLjUpICsgCiAgbGFicyh4ID0gIk1heC4gVGVtcC4gKMKwQykiLAogICAgICAgeSA9ICJNaW4uIFRlbXAuICjCsEMpIikgKyAKICBnZ3RpdGxlKCJGb3VyIFdlZWsiKSArIAogIHRoZW1lX21hdHQoKQoKZ2dhcnJhbmdlKG9uZV93ZWVrX3RlbXBfY2lyY2xlLCBmb3VyX3dlZWtfdGVtcF9jaXJjbGUsCiAgICAgICAgICBjb21tb24ubGVnZW5kID0gVCwgbGVnZW5kID0gImJvdHRvbSIpCmBgYAoKVGhlIHRoZXJtYWwgZW52aXJvbm1lbnQgb3ZlciBhbnkgcGVyaW9kIG9mIHRpbWUgbWF5IGRyaXZlIHBhdHRlcm5zIGluIHRoZXJtYWwgYWNjbGltYXRpb24uIFRvIGV4cGxvcmUgdGhlIHBvdGVudGlhbCBlZmZlY3RzIG9mIGRpZmZlcmVudCBhY2NsaW1hdGlvbiB3aW5kb3dzLCB3ZSBleGFtaW5lZCB0aGUgY29ycmVsYXRpb24gYmV0d2VlbiB0aGVybWFsIGxpbWl0cyBhbmQgZGlmZmVyZW50IHJlcHJlc2VudGF0aW9ucyBvZiB0aGUgdGhlcm1hbCBlbnZpcm9ubWVudCBmb3IgZGlmZmVyZW50IHBlcmlvZHMgb2YgdGltZS4gU2hvd24gYmVsb3cgYXJlIHRoZSBjb3JyZWxhdGlvbiBjb2VmZmljaWVudHMgZm9yIHRoZXNlIHJlbGF0aW9uc2hpcHMuIEVhY2ggZmFjZXQgc2hvd3MgdGhlIHJlbGF0aW9uc2hpcCBmb3IgYSBkaWZmZXJlbnQgZGltZW5zaW9uIG9mIHRoZSB0aGVybWFsIGVudmlyb25tZW50LiBDb3JyZWxhdGlvbiBjb2VmZmljaWVudHMgYXJlIHBsb3R0ZWQgZm9yIGRpZmZlcmVudCBkdXJhdGlvbnMsIGZvciBzcGVjaWVzIHRoYXQgd2VyZSBjb2xsZWN0ZWQgbW9yZSB0aGFuIGZpdmUgdGltZXMuIE9ubHkgZGF0YSBmb3IgbWF0dXJlIGZlbWFsZSBjb3BlcG9kcyB3YXMgaW5jbHVkZWQuIAoKV2UgY2FuIHNlZSB0aGF0LCBpbiBnZW5lcmFsLCBjb3BlcG9kcyBhcmUgcmVzcG9uZGluZyB0byBwcm94aW1hdGUgY3VlcyBmcm9tIHRoZSB0aGVybWFsIGVudmlyb25tZW50LCB3aXRoIGNvcnJlbGF0aW9ucyBnZW5lcmFsbHkgZHJvcHBpbmcgb2ZmIHN1YnN0YW50aWFsbHkgYXMgYWNjbGltYXRpb24gd2luZG93IGR1cmF0aW9uIGluY3JlYXNlcy4gQW4gZXhjZXB0aW9uIGlzICpFcGlzY2h1cmEgbGFjdXN0cmlzKiwgd2hpY2ggYXBwZWFycyB0byBiZSByZXNwb25kaW5nIHRvIG1heGltdW0gdGVtcGVyYXR1cmVzIGV4cGVyaWVuY2VkIG92ZXIgYSAyMCBkYXkgdGltZSBwZXJpb2QuIAoKYGBge3J9CiMjIyBQdWxsaW5nIHByZWRpY3RvcnMgYW5kIG1lYXN1cmluZyBjb3JyZWxhdGlvbnMgZm9yIG11Y2ggZmluZXIgdGltZXNjYWxlczsgMS01NiBkYXlzCgpudW1fY29sbHMgPSBmdWxsX2RhdGEgJT4lIAogIGZpbHRlcihzZXggPT0gImZlbWFsZSIpICU+JSAKICBzZWxlY3QoY29sbGVjdGlvbl9kYXRlLCBzcF9uYW1lKSAlPiUgIAogIGRpc3RpbmN0KCkgJT4lICAKICBjb3VudChzcF9uYW1lKSAlPiUgCiAgZmlsdGVyKG4gPj0gNSkKCmNvcnJfdmFscyA9IGRhdGEuZnJhbWUoKQoKZHVyX3ZhbHMgPSBjKDE6NTApCmZvcihpIGluIGR1cl92YWxzKXsKICAKICBkdXJhdGlvbl90ZW1wcyA9IGdldF9wcmVkaWN0b3JzKGRhaWx5X3ZhbHVlcyA9IGRhaWx5X3RlbXBfZGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXdfdGVtcCA9IHRlbXBfZGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuX2RheXMgPSBpKSAlPiUgCiAgICBmaWx0ZXIoZGF0ZSAlaW4lIGFzX2RhdGUodW5pcXVlKGZ1bGxfZGF0YSRjb2xsZWN0aW9uX2RhdGUpKSkKICAKICBjb3JyX2RhdGEgPSBmdWxsX2RhdGEgJT4lCiAgICBmaWx0ZXIoc3BfbmFtZSAlaW4lIG51bV9jb2xscyRzcF9uYW1lKSAlPiUgCiAgICBmaWx0ZXIoc2V4ID09ICJmZW1hbGUiKSAlPiUgCiAgICBtdXRhdGUoY29sbGVjdGlvbl9kYXRlID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpKSAlPiUgCiAgICBpbm5lcl9qb2luKGR1cmF0aW9uX3RlbXBzLCBqb2luX2J5KGNvbGxlY3Rpb25fZGF0ZSA9PSBkYXRlKSkgJT4lIAogICAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKGNvbGxlY3Rpb25fdGVtcCwgY29udGFpbnMoImRheV8iKSksCiAgICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInZhbHVlIiwgCiAgICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicHJlZGljdG9yIikgJT4lICAKICAgIGdyb3VwX2J5KHNwX25hbWUsIHByZWRpY3RvcikgJT4lIAogICAgc3VtbWFyaXNlKGNvcnJlbGF0aW9uID0gY29yLnRlc3QoY3RtYXgsIHZhbHVlKSRlc3RpbWF0ZSwKICAgICAgICAgICAgICBwLnZhbHVlID0gY29yLnRlc3QoY3RtYXgsIHZhbHVlKSRwLnZhbHVlLAogICAgICAgICAgICAgIGNpX2xvdyA9IGNvci50ZXN0KGN0bWF4LCB2YWx1ZSkkY29uZi5pbnRbMV0sCiAgICAgICAgICAgICAgY2lfaGlnaCA9IGNvci50ZXN0KGN0bWF4LCB2YWx1ZSkkY29uZi5pbnRbMl0sCiAgICAgICAgICAgICAgLmdyb3VwcyA9ICJrZWVwIikgJT4lIAogICAgZmlsdGVyKHByZWRpY3RvciAhPSAiY29sbGVjdGlvbl90ZW1wIikgJT4lIAogICAgbXV0YXRlKHNpZyA9IGlmZWxzZShwLnZhbHVlIDwwLjA1LCAiU2lnLiIsICJOb24gU2lnLiIpKSAlPiUgCiAgICBzZXBhcmF0ZShwcmVkaWN0b3IsICJfZGF5XyIsIGludG8gPSBjKE5BLCAicGFyYW1ldGVyIikpICU+JSAKICAgIG11dGF0ZShkdXJhdGlvbiA9IGkpCiAgCiAgY29ycl92YWxzID0gYmluZF9yb3dzKGNvcnJfdmFscywgY29ycl9kYXRhKQp9Cgpjb2xsX2NvcnIgPSBmdWxsX2RhdGEgJT4lCiAgZmlsdGVyKHNwX25hbWUgJWluJSBudW1fY29sbHMkc3BfbmFtZSkgJT4lIAogIGZpbHRlcihzZXggPT0gImZlbWFsZSIpICU+JSAKICBncm91cF9ieShzcF9uYW1lKSAlPiUgCiAgc3VtbWFyaXNlKGNvcnJlbGF0aW9uID0gY29yLnRlc3QoY3RtYXgsIGNvbGxlY3Rpb25fdGVtcCkkZXN0aW1hdGUsCiAgICAgICAgICAgIHAudmFsdWUgPSBjb3IudGVzdChjdG1heCwgY29sbGVjdGlvbl90ZW1wKSRwLnZhbHVlLAogICAgICAgICAgICBjaV9sb3cgPSBjb3IudGVzdChjdG1heCwgY29sbGVjdGlvbl90ZW1wKSRjb25mLmludFsxXSwKICAgICAgICAgICAgY2lfaGlnaCA9IGNvci50ZXN0KGN0bWF4LCBjb2xsZWN0aW9uX3RlbXApJGNvbmYuaW50WzJdKSAlPiUgCiAgbXV0YXRlKHNpZyA9IGlmZWxzZShwLnZhbHVlIDwwLjA1LCAiU2lnLiIsICJOb24gU2lnLiIpKSAlPiUgCiAgbXV0YXRlKGR1cmF0aW9uID0gMCwKICAgICAgICAgcGFyYW1ldGVyID0gImNvbGxfdGVtcCIpCgpjb3JyX3ZhbHMgPSBjb3JyX3ZhbHMgJT4lICAKICBtdXRhdGUoZHVyYXRpb24gPSBhcy5udW1lcmljKGR1cmF0aW9uKSkgJT4lIAogIGJpbmRfcm93cyhjb2xsX2NvcnIpCgpgYGAKCmBgYHtyIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD02fQpjb3JyX3ZhbHMgJT4lIAogIG11dGF0ZShwYXJhbWV0ZXIgPSBmY3RfcmVsZXZlbChwYXJhbWV0ZXIsIGMoIm1pbiIsICJtYXgiLCAicmFuZ2UiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1lYW4iLCAibWVkIiwgInZhciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibWVhbl9taW4iLCAibWVhbl9tYXgiLCAibWVhbl9yYW5nZSIpKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGR1cmF0aW9uLCB5ID0gY29ycmVsYXRpb24sIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGZhY2V0X3dyYXAoLn5wYXJhbWV0ZXIpICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCkgKyAKICBnZW9tX3BvaW50KHNpemUgPSAwLjkpICsgCiAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDEuNSkgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICBsYWJzKHggPSAiRHVyYXRpb24gKGRheXMpIiwKICAgICAgIHkgPSAiQ29ycmVsYXRpb24iLCAKICAgICAgIGNvbG91ciA9ICJTcGVjaWVzIikgKyAKICB0aGVtZV9tYXR0X2ZhY2V0cygpCmBgYAoKU2hvd24gaGVyZSBhcmUgdGhlIHRvcCB0aHJlZSBmYWN0b3JzIGZvciBlYWNoIHNwZWNpZXMuIAoKYGBge3IgcHJlZGljdG9yLWNvcnJlbGF0aW9uc30KIyAKIyBjb3JyX3ZhbHMgPSBmdWxsX2RhdGEgJT4lCiMgICBmaWx0ZXIoc3BfbmFtZSAlaW4lIG51bV9jb2xscyRzcF9uYW1lKSAlPiUgCiMgICBmaWx0ZXIoc2V4ID09ICJmZW1hbGUiKSAlPiUgCiMgICBtdXRhdGUoY29sbGVjdGlvbl9kYXRlID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpKSAlPiUgCiMgICBmdWxsX2pvaW4odGVtcF9wcmVkaWN0b3JzLCBqb2luX2J5KGNvbGxlY3Rpb25fZGF0ZSA9PSBkYXRlKSkgJT4lIAojICAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKGNvbGxlY3Rpb25fdGVtcCwgbWVhbl90ZW1wOnRhaWwobmFtZXMoLiksIDEpKSwKIyAgICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAidmFsdWUiLCAKIyAgICAgICAgICAgICAgICBuYW1lc190byA9ICJwcmVkaWN0b3IiKSAlPiUgIAojICAgZ3JvdXBfYnkoc3BfbmFtZSwgcHJlZGljdG9yKSAlPiUgCiMgICBzdW1tYXJpc2UoY29ycmVsYXRpb24gPSBjb3IudGVzdChjdG1heCwgdmFsdWUpJGVzdGltYXRlLAojICAgICAgICAgICAgIHAudmFsdWUgPSBjb3IudGVzdChjdG1heCwgdmFsdWUpJHAudmFsdWUsCiMgICAgICAgICAgICAgY2lfbG93ID0gY29yLnRlc3QoY3RtYXgsIHZhbHVlKSRjb25mLmludFsxXSwKIyAgICAgICAgICAgICBjaV9oaWdoID0gY29yLnRlc3QoY3RtYXgsIHZhbHVlKSRjb25mLmludFsyXSkgJT4lIAojICAgbXV0YXRlKHNpZyA9IGlmZWxzZShwLnZhbHVlIDwwLjA1LCAiU2lnLiIsICJOb24gU2lnLiIpKQoKY29ycl92YWxzICU+JSAgCiAgZmlsdGVyKHNpZyA9PSAiU2lnLiIpICU+JSAKICBkcm9wX25hKGNvcnJlbGF0aW9uKSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSkgJT4lCiAgYXJyYW5nZShkZXNjKGNvcnJlbGF0aW9uKSkgJT4lIAogIHNsaWNlX2hlYWQobiA9IDMpICU+JSAKICBzZWxlY3QoIlNwZWNpZXMiID0gc3BfbmFtZSwgIlByZWRpY3RvciIgPSBwYXJhbWV0ZXIsICJEdXJhdGlvbiIgPSBkdXJhdGlvbiwgIkNvcnJlbGF0aW9uIiA9IGNvcnJlbGF0aW9uLCAiUC1WYWx1ZSIgPSBwLnZhbHVlKSAlPiUgCiAga25pdHI6OmthYmxlKGFsaWduID0gImMiKQpgYGAKClBoZW5vdHlwaWMgdmFyaWF0aW9uIChsaWtlIGFjY2xpbWF0aW9uIG9mIHRoZXJtYWwgbGltaXRzKSBpcyBhIHBoeXNpb2xvZ2ljYWwgcHJvY2Vzcy4gZGVwZW5kaW5nIG9uIHRoZSBtZWNoYW5pc3RpYyB1bmRlcnBpbm5pbmdzIChjaGFuZ2VzIGluIEhTUCBleHByZXNzaW9uLCBldGMuKSwgdGhlIGFtb3VudCBvZiB0aW1lIGl0IHRha2VzIGZvciBhbiBpbmRpdmlkdWFsIHRvIGFjY2xpbWF0ZSBtYXkgdmFyeSBiYXNlZCBvbiBib2R5IHNpemUgKGxhcmdlciBzcGVjaWVzLCBtb3JlIGNlbGxzLCBtb3JlIHRpbWUgcmVxdWlyZWQgdG8gYWNjbGltYXRlKS4gU2hvd24gaGVyZSBpcyB0aGUgZHVyYXRpb24gb2YgdGhlIGVudmlyb25tZW50YWwgYWNjbGltYXRpb24gd2luZG93IHRoZSBjb3BlcG9kcyBhcHBlYXIgdG8gYmUgcmVzcG9uZGluZyB0by4gIAoKYGBge3IgYWNjLWR1cmF0aW9uLXBsb3QsIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTR9Cm1lYW5fc2l6ZXMgPSBmdWxsX2RhdGEgJT4lIAogIGZpbHRlcihzZXggPT0gImZlbWFsZSIpICU+JSAKICBncm91cF9ieShzcF9uYW1lKSAlPiUgIAogIHN1bW1hcmlzZShtZWFuX3NpemUgPSBtZWFuKHNpemUsIG5hLnJtID0gVCkpCgpjb3JyX3ZhbHMgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUpICU+JSAKICBmaWx0ZXIoY29ycmVsYXRpb24gPT0gbWF4KGNvcnJlbGF0aW9uKSkgJT4lICAKICBpbm5lcl9qb2luKG1lYW5fc2l6ZXMsIGJ5ID0gInNwX25hbWUiKSAlPiUgCiAgc2VsZWN0KHNwX25hbWUsIGR1cmF0aW9uLCBtZWFuX3NpemUpICU+JSAgCiAgZ2dwbG90KGFlcyh4ID0gbWVhbl9zaXplLCB5ID0gZHVyYXRpb24pKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IHNwX25hbWUpLCAKICAgICAgICAgICAgIHNpemUgPSA0KSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIGxhYnMoeCA9ICJNZWFuIEZlbWFsZSBTaXplIChtbSkiLAogICAgICAgeSA9ICJBY2NsaW1hdGlvbiBEdXJhdGlvbiIsCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKYGBgCgoKIyMgVHJhaXQgVmFyaWF0aW9uIApgYGB7ciBjdG1heC1hbmQtc2l6ZS1zdW0tcGxvdCwgZmlnLndpZHRoPTIwLCBmaWcuaGVpZ2h0PTV9CiMgY3RtYXhfcGxvdCA9IGZ1bGxfZGF0YSAlPiUKIyAgIG11dGF0ZSggI3NwX25hbWUgPSBzdHJfcmVwbGFjZShzcF9uYW1lLCBwYXR0ZXJuID0gIiAiLAojICAgICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQgPSAiXG4iKSwKIyAgICAgc3BfbmFtZSA9IGZjdF9yZW9yZGVyKHNwX25hbWUsIGN0bWF4LCBtZWFuKSkgJT4lCiMgICBnZ3Bsb3QoYWVzKHkgPSBzcF9uYW1lLCB4ID0gY3RtYXgpKSArCiMgICBnZW9tX3BvaW50KGFlcyhjb2xvdXI9IHNwX25hbWVfc3ViKSwKIyAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuMyksCiMgICAgICAgICAgICAgIHNpemUgPSA0KSArCiMgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKwojICAgeGxhYihOVUxMKSArCiMgICBsYWJzKHkgPSAiIiwKIyAgICAgICAgeCA9ICJDVG1heCAowrBDKSIsCiMgICAgICAgIGNvbG91ciA9ICJHcm91cCIpICsKIyAgIHRoZW1lX21hdHQoKSArCiMgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCiMgCiMgc2l6ZV9wbG90ID0gZnVsbF9kYXRhICU+JQojICAgbXV0YXRlKHNwX25hbWUgPSBmY3RfcmVvcmRlcihzcF9uYW1lLCBjdG1heCwgbWVhbikpICU+JQojICAgZ2dwbG90KGFlcyh5ID0gc3BfbmFtZSwgeCA9IHNpemUpKSArCiMgICBnZW9tX3BvaW50KGFlcyhjb2xvdXI9IHNwX25hbWVfc3ViKSwKIyAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuMyksCiMgICAgICAgICAgICAgIHNpemUgPSA0KSArCiMgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKwojICAgbGFicyh4ID0gIlByb3NvbWUgTGVuZ3RoIChtbSkiLAojICAgICAgICB5ID0gIiIsCiMgICAgICAgIGNvbG91ciA9ICJHcm91cCIpICsKIyAgIGd1aWRlcyhjb2xvciA9IGd1aWRlX2xlZ2VuZChuY29sID0gMSkpICsKIyAgIHRoZW1lX21hdHQoYmFzZV9zaXplID0gKSArCiMgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLAojICAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCksCiMgICAgICAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbigwLCAwLCAwLCAwLCJjbSIpKQojIAojIHRyYWl0X3Bsb3QgPSBjdG1heF9wbG90ICsgc2l6ZV9wbG90CiMgdHJhaXRfcGxvdApgYGAKClNob3duIGJlbG93IGFyZSB0aGUgY2x1dGNoIHNpemUgZGlzdHJpYnV0aW9ucyBmb3IgdGhlIHRocmVlIGRpYXB0b21paWQgc3BlY2llcywgd2hpY2ggcHJvZHVjZSBlZ2cgc2FjcyB0aGF0IGFsbG93IGZvciBlYXN5IHF1YW50aWZpY2F0aW9uIG9mIGZlY3VuZGl0eS4gCgpgYGB7ciBmZWN1bmRpdHktaGlzdG9ncmFtLCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD0xMH0KZnVsbF9kYXRhICU+JSAgCiAgZHJvcF9uYShmZWN1bmRpdHkpICU+JSAgCiAgZ2dwbG90KGFlcyh4ID0gZmVjdW5kaXR5LCBmaWxsID0gc3BfbmFtZV9zdWIpKSArIAogIGZhY2V0X3dyYXAoLn5zcF9uYW1lX3N1YiwgbmNvbCA9IDEpICsgCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAyKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICBsYWJzKHggPSAiRmVjdW5kaXR5ICgjIEVnZ3MpIikgKwogIHRoZW1lX21hdHRfZmFjZXRzKCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCmBgYAoKT25lIG9mIHRoZSBtYWluIGFpbXMgb2YgdGhpcyBwcm9qZWN0IGlzIHRvIGV4YW1pbmUgdGhlIHBhdHRlcm5zIGFuZCBwcm9jZXNzZXMgZHJpdmluZyB2YXJpYXRpb24gaW4gdXBwZXIgdGhlcm1hbCBsaW1pdHMgYWNyb3NzIHRoZXNlIHNwZWNpZXMgb2YgY29wZXBvZHMuIAoKIyMjIFZhcmlhdGlvbiB3aXRoIHRlbXBlcmF0dXJlIAoKV2UgZXhwZWN0IG9uZSBvZiB0aGUgcHJpbWFyeSBkcml2ZXJzIG9mIGNvcGVwb2QgdGhlcm1hbCBsaW1pdHMgdG8gYmUgdGVtcGVyYXR1cmUuIFRoZSBjb3JyZWxhdGlvbiBhbmFseXNpcyBoYXMgc2hvd24gdGhhdCB0aGUgY29wZXBvZHMgYXJlIGdlbmVyYWxseSAoYWx0aG91Z2ggbm90IGFsd2F5cykgcmVzcG9uZGluZyB0byB0aGUgcmVjZW50IHRoZXJtYWwgZW52aXJvbm1lbnQuIFNob3duIGJlbG93IGFyZSB0aGVybWFsIGxpbWl0cywgYm9keSBzaXplLCBhbmQgZmVjdW5kaXR5IHZhbHVlcyBwbG90dGVkIGFnYWluc3QgdGhlIHRlbXBlcmF0dXJlIGF0IHRoZSB0aW1lIG9mIGNvbGxlY3Rpb24uIEFsc28gc2hvd24gaXMgd2FybWluZyB0b2xlcmFuY2UsIGNhbGN1bGF0ZWQgYXMgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB1cHBlciB0aGVybWFsIGxpbWl0IGFuZCB0aGUgY29sbGVjdGlvbiB0ZW1wZXJhdHVyZS4gCgpXZSBnZW5lcmFsbHkgc2VlIGFuIGluY3JlYXNlIGluIHRoZXJtYWwgbGltaXRzIHdpdGggaW5jcmVhc2luZyBjb2xsZWN0aW9uIHRlbXBlcmF0dXJlLCBhIHNsaWdodCBkZWNyZWFzZSBpbiBib2R5IHNpemUsIGFuZCB2YXJpYWJsZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gdGVtcGVyYXR1cmUgYW5kIGZlY3VuZGl0eS4gQWxsIHNwZWNpZXMgbWFpbnRhaW5lZCBzb21lIGRlZ3JlZSBvZiBidWZmZXIgYmV0d2VlbiBlbnZpcm9ubWVudGFsIHRlbXBlcmF0dXJlcyBhbmQgdXBwZXIgdGhlcm1hbCBsaW1pdHMsIGJ1dCAqRXBpc2NodXJhKiBhbmQgKkwuIG1pbnV0dXMqIGFwcHJvYWNoZWQgdGhlaXIgdXBwZXIgdGhlcm1hbCBsaW1pdHMgZHVyaW5nIHRoZSB3YXJtZXN0IGNvbGxlY3Rpb25zIGR1cmluZyB0aGUgc3VtbWVyLiAKCmBgYHtyIHRyYWl0LWNvbGwtdGVtcC1wbG90cywgZmlnLndpZHRoPTE1LCBmaWcuaGVpZ2h0PTEwfQpjdG1heF90ZW1wID0gZ2dwbG90KGZ1bGxfZGF0YSwgYWVzKHggPSBjb2xsZWN0aW9uX3RlbXAsIHkgPSBjdG1heCwgY29sb3VyID0gc3BfbmFtZSkpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgbGluZXdpZHRoID0gMykgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsgCiAgbGFicyh4ID0gIkNvbGxlY3Rpb24gVGVtcGVyYXR1cmUgKMKwQykiLCAKICAgICAgIHkgPSAiQ1RtYXggKMKwQykiLAogICAgICAgY29sb3VyID0gIlNwZWNpZXMiKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpzaXplX3RlbXAgPSBnZ3Bsb3QoZmlsdGVyKGZ1bGxfZGF0YSwgc2V4ICE9ICJqdXZlbmlsZSIpLCBhZXMoeCA9IGNvbGxlY3Rpb25fdGVtcCwgeSA9IHNpemUsIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGxpbmV3aWR0aCA9IDMpICsKICBnZW9tX3BvaW50KHNpemUgPSAzKSArIAogIGxhYnMoeCA9ICJDb2xsZWN0aW9uIFRlbXBlcmF0dXJlICjCsEMpIiwgCiAgICAgICB5ID0gIkxlbmd0aCAobW0pIiwKICAgICAgIGNvbG91ciA9ICJTcGVjaWVzIikgICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKCnd0X3RlbXAgPSBnZ3Bsb3QoZnVsbF9kYXRhLCBhZXMoeCA9IGNvbGxlY3Rpb25fdGVtcCwgeSA9IHdhcm1pbmdfdG9sLCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBsaW5ld2lkdGggPSAzKSArCiAgZ2VvbV9wb2ludChzaXplID0gMykgKyAKICBsYWJzKHggPSAiQ29sbGVjdGlvbiBUZW1wZXJhdHVyZSAowrBDKSIsIAogICAgICAgeSA9ICJXYXJtaW5nIFRvbGVyYW5jZSAowrBDKSIsCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgplZ2dzX3RlbXAgPSBnZ3Bsb3QoZnVsbF9kYXRhLCBhZXMoeCA9IGNvbGxlY3Rpb25fdGVtcCwgeSA9IGZlY3VuZGl0eSwgY29sb3VyID0gc3BfbmFtZSkpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgbGluZXdpZHRoID0gMykgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsgCiAgbGFicyh4ID0gIkNvbGxlY3Rpb24gVGVtcGVyYXR1cmUgKMKwQykiLCAKICAgICAgIHkgPSAiRmVjdW5kaXR5ICgjIEVnZ3MpIiwKICAgICAgIGNvbG91ciA9ICJTcGVjaWVzIikgICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKCmdnYXJyYW5nZShjdG1heF90ZW1wLCBzaXplX3RlbXAsIHd0X3RlbXAsIGVnZ3NfdGVtcCwgCiAgICAgICAgICBjb21tb24ubGVnZW5kID0gVCwgbGVnZW5kID0gInJpZ2h0IikKYGBgCgpgYGB7ciBmaWcud2lkdGg9NywgZmlnLmhlaWdodD01fQpmdWxsX2RhdGEgJT4lIAogICNmaWx0ZXIoc2V4ID09ICJmZW1hbGUiKSAlPiUgIAogIGdyb3VwX2J5KHNwX25hbWUpICU+JSBmaWx0ZXIobigpID4gNSkgJT4lIGZpbHRlcighc3RyX2RldGVjdChzcF9uYW1lLCBwYXR0ZXJuID0gImtpbmR0aSIpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gY29sbGVjdGlvbl90ZW1wLCB5ID0gY3RtYXgsIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGZhY2V0X3dyYXAoc3BfbmFtZX4uKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDIsIGFscGhhID0gMC44KSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgbGluZXdpZHRoID0gMikgKyAKICBsYWJzKHggPSAiQ29sbGVjdGlvbiBUZW1wLiAowrBDKSIsIAogICAgICAgeSA9ICJDVG1heCAowrBDKSIpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpgYGAKClRlbXBlcmF0dXJlIGRlcGVuZGVuY2UgaXMgcmVsYXRpdmVseSB3ZWFrIGluICpMLiBzaWNpbGlzKiwgZXNwZWNpYWxseSBhdCBjb29sZXIgdGVtcGVyYXR1cmVzLiBXZSB3aWxsIHJldHVybiB0byB0aGlzIGZlYXR1cmUgbGF0ZXIgaW4gdGhlIHJlcG9ydCwgYnV0IGZvciBub3cgd2Ugd2lsbCBub3RlIHRoYXQgdGhlcmUgYXJlIHR3byBzaXplIG1vcnBocyBpbiB0aGlzIHNwZWNpZXMsIHdoaWNoIGFwcGVhciB0byByZXNwb25kIGRpZmZlcmVudGx5IHRvIGRlY3JlYXNlcyBpbiB0ZW1wZXJhdHVyZS4gVGhlcmUgYXJlIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzIGJldHdlZW4gdGhlIG1vcnBocyBhbmQgaG93IHRlbXBlcmF0dXJlIGFmZmVjdHMgQ1RtYXguIAoKYGBge3J9Cm1vcnBoX2RhdGEgPSBmdWxsX2RhdGEgJT4lIAogIGZpbHRlcihzZXggPT0gImZlbWFsZSIgJiBzcF9uYW1lID09ICJMZXB0b2RpYXB0b211cyBzaWNpbGlzIikgJT4lIAogIG11dGF0ZShtb3JwaCA9IGlmX2Vsc2Uoc2l6ZSA+IDAuODksICJsYXJnZSIsICJzbWFsbCIpKQoKZ2dwbG90KG1vcnBoX2RhdGEsIGFlcyh4ID0gY29sbGVjdGlvbl90ZW1wLCB5ID0gY3RtYXgsIGNvbG91ciA9IG1vcnBoKSkgKyAKICBnZW9tX3BvaW50KHNpemUgPSAyLCBhbHBoYSA9IDAuOCkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IFQsIGxpbmV3aWR0aCA9IDIpICsgCiAgbGFicyh4ID0gIkNvbGxlY3Rpb24gVGVtcC4gKMKwQykiLCAKICAgICAgIHkgPSAiQ1RtYXggKMKwQykiKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKCm1vcnBoLm1vZGVsID0gbG0oZGF0YSA9IG1vcnBoX2RhdGEsIAogICAgICAgICAgICAgICAgIGN0bWF4IH4gY29sbGVjdGlvbl90ZW1wICogbW9ycGgpCgprbml0cjo6a2FibGUoY2FyOjpBbm92YShtb3JwaC5tb2RlbCwgdHlwZSA9ICJJSUkiLCB0ZXN0ID0gIkYiKSkKCiNzdW1tYXJ5KG1vcnBoLm1vZGVsKQoKI21vcnBoLmVtID0gZW1tZWFuczo6ZW1tZWFucyhtb3JwaC5tb2RlbCwgcGFpcndpc2UgfiBtb3JwaCkKCiNwbG90KG1vcnBoLmVtKQpgYGAKCmBgYHtyIGN0bWF4LXJhbmdlLXBsb3QsIGluY2x1ZGUgPSBGfQpmdWxsX2RhdGEgJT4lICAKICBmaWx0ZXIoc2V4ID09ICJmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSwgY29sbGVjdGlvbl9kYXRlLCBjb2xsZWN0aW9uX3RlbXApICU+JSAgCiAgc3VtbWFyaXNlKCJjdG1heF9yYW5nZSIgPSBtYXgoY3RtYXgpIC0gbWluKGN0bWF4KSwKICAgICAgICAgICAgImN0bWF4X3ZhciIgPSB2YXIoY3RtYXgpLAogICAgICAgICAgICAic2FtcGxlX3NpemUiID0gbigpKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBncm91cF9ieShzcF9uYW1lKSAlPiUgCiAgZmlsdGVyKHNwX25hbWUgIT0gIkxlcHRvZG9yYSBraW5kdGkiKSAlPiUgCiAgZmlsdGVyKHNhbXBsZV9zaXplID4gMykgJT4lIAogIGdncGxvdChhZXMoeCA9IGNvbGxlY3Rpb25fdGVtcCwgeSA9IGN0bWF4X3ZhciwgY29sb3VyID0gc3BfbmFtZSkpICsgCiAgZmFjZXRfd3JhcChzcF9uYW1lfi4pICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgY29sb3VyID0gImJsYWNrIikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICB0aGVtZV9tYXR0X2ZhY2V0cygpCmBgYAoKCmBgYHtyIGN0bWF4LWNvbGwtdGVtcC1tb2RlbCwgaW5jbHVkZSA9IEZ9CiMgYWR1bHRfZGF0YSA9IGZ1bGxfZGF0YSAlPiUgCiMgICBmaWx0ZXIoc2V4ID09ICJmZW1hbGUiKQptb2RlbF9kYXRhID0gZnVsbF9kYXRhICU+JSAgCiAgZHJvcF9uYShzaXplLCBjdG1heCkgJT4lICAKICBtdXRhdGUodGVtcF9jZW50ID0gc2NhbGUoY29sbGVjdGlvbl90ZW1wLCBjZW50ZXIgPSBULCBzY2FsZSA9IEYpLAogICAgICAgICBzaXplX2NlbnQgPSBzY2FsZShzaXplLCBjZW50ZXIgPSBULCBzY2FsZSA9IEYpKQoKY3RtYXhfdGVtcC5tb2RlbCA9IGxtKGRhdGEgPSBtb2RlbF9kYXRhLCBjdG1heCB+IHRlbXBfY2VudCAqIHNwX25hbWUpCnNpemVfdGVtcC5tb2RlbCA9IGxtKGRhdGEgPSBtb2RlbF9kYXRhLCBzaXplIH4gY29sbGVjdGlvbl90ZW1wICogc3BfbmFtZSkKCmtuaXRyOjprYWJsZShjYXI6OkFub3ZhKGN0bWF4X3RlbXAubW9kZWwpKQoKY3RtYXhfcmVzaWRzID0gY2JpbmQobW9kZWxfZGF0YSwgInJlc2lkcyIgPSBjdG1heF90ZW1wLm1vZGVsJHJlc2lkdWFscywgInNpemVfcmVzaWRzIiA9IHNpemVfdGVtcC5tb2RlbCRyZXNpZHVhbHMpCgpgYGAKCkNvcGVwb2RzIHNwZW50IHNldmVyYWwgZGF5cyBpbiBsYWIgZHVyaW5nIGV4cGVyaW1lbnRzLiBTaG93biBiZWxvdyBhcmUgdGhlIENUbWF4IHJlc2lkdWFscyAodGFrZW4gZnJvbSBhIG1vZGVsIG9mIENUbWF4IGFnYWluc3QgY29sbGVjdGlvbiB0ZW1wZXJhdHVyZSkgcGxvdHRlZCBhZ2FpbnN0IHRoZSB0aW1lIHNwZW50IGluIGxhYiBiZWZvcmUgbWVhc3VyZW1lbnRzIHdlcmUgbWFkZS4gSW5kaXZpZHVhbCByZWdyZXNzaW9ucyBhcmUgc2hvd24gZm9yIHRoZSByZXNpZHVhbHMgYWdhaW5zdCBkYXlzIGluIGxhYiBmb3IgZWFjaCBjb2xsZWN0aW9uLiBXZSBjYW4gc2VlIGNsZWFybHkgdGhhdCB0aGVybWFsIGxpbWl0cyBhcmUgZmFpcmx5IHN0YWJsZSBvdmVyIHRpbWUuIAoKYGBge3IgY3RtYXgtdGltZS1pbi1sYWIsIGZpZy53aWR0aD0xNSwgZmlnLmhlaWdodD0xMH0KZ2dwbG90KGN0bWF4X3Jlc2lkcywgYWVzKHggPSBkYXlzX2luX2xhYiwgeSA9IHJlc2lkcywgY29sb3VyID0gc3BfbmFtZSwgZ3JvdXAgPSBjb2xsZWN0aW9uX2RhdGUpKSArIAogIGZhY2V0X3dyYXAoc3BfbmFtZX4uKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDQsIGFscGhhID0gMC41KSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgbGluZXdpZHRoID0gMSkgKyAKICAjc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGMoMDo1KSkgKyAKICBsYWJzKHggPSAiRGF5cyBpbiBsYWIiLCAKICAgICAgIHkgPSAiQ1RtYXggUmVzaWR1YWxzIikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICB0aGVtZV9tYXR0X2ZhY2V0cygpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpgYGAKCmBgYHtyIGluY2x1ZGUgPSBGfQpjdG1heF9yZXNpZHMgJT4lIAogIGZpbHRlcihsaXBpZHMgIT0gInVuY2VydGFpbiIpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBsaXBpZHMsIHkgPSByZXNpZHMsIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGZhY2V0X3dyYXAoc3BfbmFtZX4uKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDQsIGFscGhhID0gMC41KSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgbGluZXdpZHRoID0gMSkgKyAKICAjc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGMoMDo1KSkgKyAKICBsYWJzKHggPSAiRGF5cyBpbiBsYWIiLCAKICAgICAgIHkgPSAiQ1RtYXggUmVzaWR1YWxzIikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICB0aGVtZV9tYXR0X2ZhY2V0cygpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpgYGAKCmBgYHtyIEFSUi1saW1pdHMtcGxvdCwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Nn0KZnVsbC5tb2RlbCA9IGxtZTQ6OmxtZXIoZGF0YSA9IG1vZGVsX2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgIGN0bWF4IH4gc2V4ICsgdGVtcF9jZW50ICsgc2l6ZV9jZW50ICsKICAgICAgICAgICAgICAgICAgICAgICAgICAoMSArIGRheXNfaW5fbGFiICsgdGVtcF9jZW50ICsgc2l6ZV9jZW50fHNwX25hbWUpKQoKY2FyOjpBbm92YShmdWxsLm1vZGVsKQoKZml4ZWQgPSBmaXhlZihmdWxsLm1vZGVsKQoKbW9kZWxfY29lZnMgPSBjb2VmZmljaWVudHMoZnVsbC5tb2RlbCkkYHNwX25hbWVgICU+JSAgCiAgcm93bmFtZXNfdG9fY29sdW1uKHZhciA9ICJzcGVjaWVzIikgJT4lIAogIHNlcGFyYXRlKHNwZWNpZXMsIGludG8gPSBjKCJzcGVjaWVzIiksIHNlcCA9ICI6IikgJT4lIAogIHNlbGVjdChzcGVjaWVzLCAiaW50ZXJjZXB0IiA9ICIoSW50ZXJjZXB0KSIsIHRlbXBfY2VudCwgc2l6ZV9jZW50LCBkYXlzX2luX2xhYikKCmdncGxvdChtb2RlbF9jb2VmcywgYWVzKHggPSBpbnRlcmNlcHQsIHkgPSB0ZW1wX2NlbnQpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGNvbG91ciA9ICJibGFjayIpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBzcGVjaWVzKSwKICAgICAgICAgICAgIHNpemUgPSA2KSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIGxhYnMoeCA9ICJTcGVjaWVzIEludGVyY2VwdCIsIAogICAgICAgeSA9ICJBUlIiKSArCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKYGBgCgoKVGhlIHRlcm0gImFjY2xpbWF0aW9uIHJlc3BvbnNlIHJhdGlvIiBpcyBvZnRlbiB1c2VkIHRvIGRlc2NyaWJlIHRoZSBlZmZlY3Qgb2YgdGVtcGVyYXR1cmUgb24gdGhlcm1hbCBsaW1pdHMuIFRoZSBBUlIgaXMgY2FsY3VsYXRlZCBhcyB0aGUgY2hhbmdlIGluIHRoZXJtYWwgbGltaXRzIHBlciBkZWdyZWUgY2hhbmdlIGluIGFjY2xpbWF0aW9uIHRlbXBlcmF0dXJlLiBGb3Igb3VyIGRhdGEsIHdlIHdpbGwgZXN0aW1hdGUgQVJSIGFzIHRoZSBzbG9wZSBvZiBDVG1heCBhZ2FpbnN0IGNvbGxlY3Rpb24gdGVtcGVyYXR1cmUuIFRoZXNlIHNsb3BlcyB3ZXJlIHRha2VuIGZyb20gYSByZWdyZXNzaW9uIG9mIENUbWF4IGFnYWluc3QgY29sbGVjdGlvbiB0ZW1wZXJhdHVyZSBhbmQgYm9keSBzaXplLiBUd28gZGlmZmVyZW50IG1vZGVsIHR5cGVzIHdlcmUgdXNlZCwgYSBzaW1wbGUgbGluZWFyIHJlZ3Jlc3Npb24gYW5kIGEgbWl4ZWQgZWZmZWN0cyBtb2RlbC4gVGhlIGVzdGltYXRlZCBBUlIgdmFsdWVzIHdlcmUgZ2VuZXJhbGx5IGhpZ2hseSBzaW1pbGFyIGJldHdlZW4gdGhlIG1vZGVsIHR5cGVzIHVzZWQuCgpgYGB7ciBhcnItY29tcC1wbG90LCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD0xMCwgaW5jbHVkZSA9IEZ9CmNvZWZfbW9kZWxfZGF0YSA9IGZ1bGxfZGF0YSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSwgc2V4KSAlPiUgCiAgZmlsdGVyKG4oKSA+IDMgJiAhc3RyX2RldGVjdChzcF9uYW1lLCBwYXR0ZXJuID0gImtpbmR0aSIpKSAKCmNvZWZfbiA9IGZ1bGxfZGF0YSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSwgc2V4KSAlPiUgCiAgZmlsdGVyKG4oKSA+IDUpICU+JSAKICBzdW1tYXJpc2Uoc2FtcGxlX24gPSBuKCksIAogICAgICAgICAgICBtZWFuX2N0bWF4ID0gbWVhbihjdG1heCkpCgpBUlJfdmFscyA9IGNvZWZfbW9kZWxfZGF0YSAlPiUgCiAgZG8oYnJvb206OnRpZHkobG0oY3RtYXggfiBjb2xsZWN0aW9uX3RlbXAgKyBzaXplLCBkYXRhID0gLikpKSAlPiUgCiAgZmlsdGVyKHRlcm0gPT0gImNvbGxlY3Rpb25fdGVtcCIpICU+JSAKICBzZWxlY3Qoc3BfbmFtZSwgc2V4LCAiQVJSIiA9IGVzdGltYXRlLCBzdGQuZXJyb3IpICU+JSAKICBhcnJhbmdlKEFSUikgJT4lIAogIGlubmVyX2pvaW4oY29lZl9uLCBieSA9IGMoInNwX25hbWUiLCAic2V4IikpCgpBUlJfdmFscyAlPiUgCiAgc2VsZWN0KCJTcGVjaWVzIiA9IHNwX25hbWUsIAogICAgICAgICAiR3JvdXAiID0gc2V4LCAKICAgICAgICAgIk4iID0gc2FtcGxlX24sCiAgICAgICAgIEFSUiwgCiAgICAgICAgICJFcnJvciIgPSBzdGQuZXJyb3IpICU+JSAKICBrbml0cjo6a2FibGUoKQoKbWxlX2NvZWZzID0gY29lZmZpY2llbnRzKGZ1bGwubW9kZWwpJGBzcF9uYW1lYCAlPiUgCiAgbXV0YXRlKCJncm91cCIgPSByb3duYW1lcyguKSkgJT4lIAogIHNlbGVjdChncm91cCwgImludGVyY2VwdCIgPSAiKEludGVyY2VwdCkiLCAiQVJSIiA9IHRlbXBfY2VudCwgc2l6ZV9jZW50KSAlPiUgCiAgcmVtb3ZlX3Jvd25hbWVzKCkKCm1sZV9BUlIgPSBtbGVfY29lZnMgJT4lICAKICBzZWxlY3Qoc3BfbmFtZSA9IGdyb3VwLCBBUlIpICU+JSAKICBtdXRhdGUoIm1vZGVsIiA9ICJtaXhlZCBlZmZlY3RzIikgICU+JSAKICBpbm5lcl9qb2luKGNvZWZfbiwgYnkgPSBjKCJzcF9uYW1lIikpCgpBUlJfY29tcCA9IGJpbmRfcm93cyhtbGVfQVJSLCAKICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKEFSUl92YWxzLCAibW9kZWwiID0gImxpbmVhciIpKQoKQVJSX2NvbXAgJT4lIAogIGdncGxvdChhZXMoeCA9IG1vZGVsLCB5ID0gQVJSLCBncm91cCA9IHNwX25hbWUpKSArIAogIGZhY2V0X2dyaWQoc3BfbmFtZX5zZXgpICsKICBnZW9tX3BvaW50KHNpemUgPSAzKSArIAogIGdlb21fbGluZShsaW5ld2lkdGggPSAxLjUpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoMCwgMC41LCAxKSkgKyAKICB0aGVtZV9tYXR0X2ZhY2V0cygpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMDAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpKQoKYGBgCgojIyMgU2V4IGFuZCBzdGFnZSB2YXJpYXRpb24gaW4gdGhlcm1hbCBsaW1pdHMgClByZXZpb3VzIHNlY3Rpb25zIGhhdmUgZ2VuZXJhbGx5IGx1bXBlZCBqdXZlbmlsZSwgZmVtYWxlLCBhbmQgbWFsZSBpbmRpdmlkdWFscyB0b2dldGhlci4gVGhlcmUgbWF5IGJlIGltcG9ydGFudCBzdGFnZS0gb3Igc2V4LXNwZWNpZmljIGRpZmZlcmVuY2VzIGluIENUbWF4IHRob3VnaC4gRm9yIHNldmVyYWwgc3BlY2llcywgd2UgaGF2ZSBtZWFzdXJlbWVudHMgZm9yIGluZGl2aWR1YWxzIGluIGRpZmZlcmVudCBzdGFnZXMgb3Igb2YgZGlmZmVyZW50IHNleGVzLiAKCmBgYHtyIHNleC1zdGFnZS10YWJsZX0Kc2V4X3NhbXBsZV9zaXplcyA9IGN0bWF4X3Jlc2lkcyAlPiUgIAogIGdyb3VwX2J5KHNwX25hbWUsIHNleCkgJT4lICAKICBzdW1tYXJpc2UobnVtID0gbigpKSAlPiUgIAogIHBpdm90X3dpZGVyKGlkX2NvbHMgPSBzcF9uYW1lLAogICAgICAgICAgICAgIG5hbWVzX2Zyb20gPSBzZXgsIAogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gbnVtLAogICAgICAgICAgICAgIHZhbHVlc19maWxsID0gMCkgJT4lIAogIHNlbGVjdCgiU3BlY2llcyIgPSBzcF9uYW1lLCAiSnV2ZW5pbGUiID0ganV2ZW5pbGUsICJGZW1hbGUiID0gZmVtYWxlLCAiTWFsZSIgPSBtYWxlKQoKa25pdHI6OmthYmxlKHNleF9zYW1wbGVfc2l6ZXMsIGFsaWduID0gImMiKQpgYGAKClRoZSBmZW1hbGUtbWFsZSBhbmQgZmVtYWxlLWp1dmVuaWxlIGNvbXBhcmlzb25zIHNob3cgdGhhdCB0aGVyZSBhcmUgZ2VuZXJhbGx5IG5vIGRpZmZlcmVuY2VzIGluIHRoZXJtYWwgbGltaXRzIGJldHdlZW4gdGhlc2UgZ3JvdXBzLiAKCmBgYHtyIGN0bWF4LXNleCwgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9N30KY3RtYXhfcmVzaWRzICU+JSAKICBmaWx0ZXIoc3BfbmFtZSAlaW4lIGZpbHRlcihzZXhfc2FtcGxlX3NpemVzLCBNYWxlID4gMCwgRmVtYWxlID4gMCkkU3BlY2llcyAmIAogICAgICAgICAgIHNleCAhPSAianV2ZW5pbGUiKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gc2V4LCB5ID0gcmVzaWRzLCBjb2xvdXIgPSBzcF9uYW1lLCBncm91cCA9IHNwX25hbWUpKSArIAogIGZhY2V0X3dyYXAoc3BfbmFtZX4uLCBuY29sID0gMikgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYsIGxpbmV3aWR0aCA9IDEpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMywKICAgICAgICAgICAgIGFscGhhID0gMC41LAogICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIoaGVpZ2h0ID0gMCwgd2lkdGggPSAwLjA1KSkgKyAgCiAgbGFicyh4ID0gIlNleCIsIAogICAgICAgeSA9ICJDVG1heCBSZXNpZHVhbHMiKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDE4KSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgCiAgICAgICAgcGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSkKYGBgCgpgYGB7ciBjdG1heC1zdGFnZSwgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9N30KY3RtYXhfcmVzaWRzICU+JSAKICBmaWx0ZXIoc3BfbmFtZSAlaW4lIGZpbHRlcihzZXhfc2FtcGxlX3NpemVzLCBKdXZlbmlsZSA+IDAgJiBGZW1hbGUgPiAwKSRTcGVjaWVzICYgCiAgICAgICAgICAgc2V4ICE9ICJtYWxlIikgJT4lIAogIGdncGxvdChhZXMoeCA9IHNleCwgeSA9IHJlc2lkcywgY29sb3VyID0gc3BfbmFtZSwgZ3JvdXAgPSBzcF9uYW1lKSkgKyAKICBmYWNldF93cmFwKHNwX25hbWV+LiwgbmNvbCA9IDIpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGLCBsaW5ld2lkdGggPSAxKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDMsCiAgICAgICAgICAgICBhbHBoYSA9IDAuNSwKICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyKGhlaWdodCA9IDAsIHdpZHRoID0gMC4wNSkpICsgIAogIGxhYnMoeCA9ICJTZXgiLCAKICAgICAgIHkgPSAiQ1RtYXggKMKwQykiKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDE4KSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgCiAgICAgICAgcGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSkKYGBgCgpgYGB7ciB0cmFpdC12YXJpYW5jZS1jb2xsLXRlbXAsIGluY2x1ZGUgPSBGfQojIAojIEdpdmVuIHRoZSBsb25nIGdlbmVyYXRpb24gdGltZXMgb2YgdGhlc2UgY29wZXBvZHMsIGRlY3JlYXNlcyBpbiB0cmFpdCB2YXJpYW5jZSBtYXkgaW5kaWNhdGUgc2VsZWN0aW9uIG92ZXIgdGhlIHNlYXNvbmFsIGN5Y2xlLiBTaG93biBiZWxvdyBhcmUgdGhlIHZhcmlhbmNlIGluIG9ic2VydmVkIENUbWF4IGFuZCBzaXplLCBwbG90dGVkIGFnYWluc3QgY29sbGVjdGlvbiBkYXRlLiBWYXJpYW5jZSBkZWNyZWFzZXMgaW4gKlNraXN0b2RpYXB0b211cyosIGJ1dCB0aGlzIHBhdHRlcm4gaXMgZHJpdmVuIGJ5IGEgc2luZ2xlIGNvbGxlY3Rpb24gd2l0aCBoaWdoIHZhcmlhbmNlIGVhcmx5IGluIHRoZSB5ZWFyLiBTaXplIHZhcmlhbmNlIGluY3JlYXNlcyBzbGlnaHRseSBpbiAqU2tpc3RvZGlhcHRvbXVzKi4gVmFyaWFuY2UgaW4gYm90aCBDVG1heCBhbmQgc2l6ZSBpcyBmYWlybHkgY29uc3RhbnQgaW4gKkxlcHRvZGlhcHRvbXVzIG1pbnV0dXMqLCB0aGUgb25seSBvdGhlciBzcGVjaWVzIGNvbGxlY3RlZCBhY3Jvc3MgdGhlIGVudGlyZSBzZXQgb2Ygc2FtcGxlcyB0aHVzIGZhci4gCiMgCiMgZ2dwbG90KGRyb3BfbmEoYWR1bHRfc3VtbWFyaWVzLCBjdG1heF92YXIpLCBhZXMoeCA9IGFzLkRhdGUoY29sbGVjdGlvbl9kYXRlKSwgeSA9IGN0bWF4X3ZhciwgY29sb3VyID0gc3BfbmFtZSkpICsgCiMgICBmYWNldF93cmFwKHNwX25hbWV+Liwgc2NhbGVzID0gImZyZWVfeSIpICsgCiMgICBnZW9tX3BvaW50KHNpemUgPSAyKSArIAojICAgZ2VvbV9zbW9vdGgoc2UgPSBGKSArIAojICAgbGFicyh4ID0gIkNvbGxlY3Rpb24gVGVtcC4gKMKwQykiLCAKIyAgICAgICAgeSA9ICJDVG1heCBWYXJpYW5jZSIpICsgCiMgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKIyAgIHRoZW1lX21hdHRfZmFjZXRzKCkgKyAKIyAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKIyAKIyBnZ3Bsb3QoZHJvcF9uYShhZHVsdF9zdW1tYXJpZXMsIHNpemVfdmFyKSwgYWVzKHggPSBhcy5EYXRlKGNvbGxlY3Rpb25fZGF0ZSksIHkgPSBzaXplX3ZhciwgY29sb3VyID0gc3BfbmFtZSkpICsgCiMgICBmYWNldF93cmFwKHNwX25hbWV+LikgKyAKIyAgIGdlb21fcG9pbnQoc2l6ZSA9IDIpICsgCiMgICBnZW9tX3Ntb290aChzZSA9IEYpICsgCiMgICBsYWJzKHggPSAiQ29sbGVjdGlvbiBUZW1wLiAowrBDKSIsIAojICAgICAgICB5ID0gIlNpemUgVmFyaWFuY2UiKSArIAojICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiMgICB0aGVtZV9tYXR0X2ZhY2V0cygpICsgCiMgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCmBgYAoKCiMjIyBUcmFpdCBDb3JyZWxhdGlvbnMgYW5kIFRyYWRlLW9mZnMKCkEgcmVsYXRpb25zaGlwIGJldHdlZW4gc2l6ZSBhbmQgdXBwZXIgdGhlcm1hbCBsaW1pdHMgaGFzIGJlZW4gc3VnZ2VzdGVkIGluIGEgd2lkZSByYW5nZSBvZiBvdGhlciB0YXhhLiBTaG93biBiZWxvdyBhcmUgdGhlIG1lYXN1cmVkIHVwcGVyIHRoZXJtYWwgbGltaXRzIHBsb3R0ZWQgYWdhaW5zdCBwcm9zb21lIGxlbmd0aC4gVGhlIG92ZXJhbGwgcmVsYXRpb25zaGlwIChpbmNsdXNpdmUgb2YgYWxsIHNwZWNpZXMpIGlzIHNob3duIGFzIHRoZSBibGFjayBsaW5lIGluIHRoZSBiYWNrZ3JvdW5kLiBSZWdyZXNzaW9ucyBmb3IgZWFjaCBpbmRpdmlkdWFsIHNwZWNpZXMgYXJlIGFsc28gc2hvd24uIEFjcm9zcyB0aGUgZW50aXJlIGFzc2VtYmxhZ2UsIHRoZXJlIGlzIGEgc3Ryb25nIGRlY3JlYXNlIGluIHRoZXJtYWwgbGltaXRzIHdpdGggaW5jcmVhc2luZyBzaXplLiAgCgpgYGB7ciBjdG1heC1zaXplLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9N30KCmZ1bGxfZGF0YSAlPiUgCiAgI2ZpbHRlcihzZXggPT0gImZlbWFsZSIpICU+JSAgCiAgZ2dwbG90KCBhZXMoeCA9IHNpemUsIHkgPSBjdG1heCwgY29sb3VyID0gc3BfbmFtZSkpICsgCiAgZ2VvbV9zbW9vdGgoZGF0YSA9IGZ1bGxfZGF0YSwgCiAgICAgICAgICAgICAgYWVzKHggPSBzaXplLCB5ID0gY3RtYXgpLAogICAgICAgICAgICAgIG1ldGhvZCA9ICJsbSIsIAogICAgICAgICAgICAgIGNvbG91ciA9ImJsYWNrIiwgCiAgICAgICAgICAgICAgbGluZXdpZHRoID0gMi41KSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDIsIGFscGhhID0gMC4zKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgbGluZXdpZHRoID0gMikgKyAKICBsYWJzKHggPSAiTGVuZ3RoIChtbSkiLCAKICAgICAgIHkgPSAiQ1RtYXggKMKwQykiLAogICAgICAgY29sb3VyID0gIlNwZWNpZXMiKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpgYGAKClNob3duIGhlcmUgaXMgdGhlIHJlbGF0aW9uc2hpcCBmb3IgZWFjaCBzcGVjaWVzIGluZGl2aWR1YWxseS4gCgpgYGB7ciBpbmQtc3AtY3RtYXgtc2l6ZSwgZmlnLndpZHRoPTksIGZpZy5oZWlnaHQ9Nn0KZnVsbF9kYXRhICU+JSAKICAjZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lICAKICBncm91cF9ieShzcF9uYW1lKSAlPiUgZmlsdGVyKG4oKSA+MikgJT4lIGZpbHRlcighc3RyX2RldGVjdChzcF9uYW1lLCBwYXR0ZXJuID0gImtpbmR0aSIpKSAlPiUgCiAgZ2dwbG90KCBhZXMoeCA9IHNpemUsIHkgPSBjdG1heCwgY29sb3VyID0gc3BfbmFtZSkpICsgCiAgZmFjZXRfd3JhcChzcF9uYW1lfi4sIHNjYWxlcyA9ICJmcmVlIiwgbnJvdyA9IDIpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMiwgYWxwaGEgPSAwLjgpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGLCBsaW5ld2lkdGggPSAyKSArIAogIGxhYnMoeCA9ICJMZW5ndGggKG1tKSIsIAogICAgICAgeSA9ICJDVG1heCAowrBDKSIsCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpgYGAKClNob3duIGJlbG93IGlzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBtZWFuIHNpemUgYW5kIG1lYW4gdGhlcm1hbCBsaW1pdHMgZm9yIGZlbWFsZXMgb2YgZWFjaCBzcGVjaWVzLiBXZSBzZWUgdGhhdCBsYXJnZXIgc3BlY2llcyB3aXRoaW4gdGhlIGNvbW11bml0eSB0ZW5kIHRvIGhhdmUgYSBsb3dlciB0aGVybWFsIGxpbWl0IHRoYW4gc21hbGxlciBzcGVjaWVzLiAKCmBgYHtyIG1lYW4tY3RtYXgtbWVhbi1zaXplLXBsb3QsIGZpZy53aWR0aD05LCBmaWcuaGVpZ2h0PTV9CmZ1bGxfZGF0YSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSwgc2V4KSAlPiUgCiAgc3VtbWFyaXplKG1lYW5fY3RtYXggPSBtZWFuKGN0bWF4LCBuYS5ybSA9IFQpLAogICAgICAgICAgICBtZWFuX3NpemUgPSBtZWFuKHNpemUsIG5hLnJtID0gVCkpICU+JSAKICAjZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lIAogIGdncGxvdChhZXMoeCA9IG1lYW5fc2l6ZSwgeSA9IG1lYW5fY3RtYXgpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgbGluZXdpZHRoID0gMiwgY29sb3VyID0gImJsYWNrIikgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBzcF9uYW1lLCBzaGFwZSA9IHNleCksCiAgICAgICAgICAgICBzaXplID0gNSkgKyAKICBsYWJzKHggPSAiTGVuZ3RoIChtbSkiLCAKICAgICAgIHkgPSAiQ1RtYXggKMKwQykiLAogICAgICAgY29sb3VyID0gIlNwZWNpZXMiKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCmBgYAoKYGBge3IgY3RtYXhyZXNpZHMtc2l6ZSwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTcsIGluY2x1ZGUgPSBGfQpjdG1heF9yZXNpZHMgJT4lIAogICNmaWx0ZXIoc2V4ID09ICJmZW1hbGUiKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gc2l6ZV9yZXNpZHMsIHkgPSByZXNpZHMsIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGZhY2V0X3dyYXAoc3BfbmFtZX4uKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDIpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGLCBsaW5ld2lkdGggPSAyKSArIAogIGxhYnMoeCA9ICJMZW5ndGggKG1tKSIsIAogICAgICAgeSA9ICJDVG1heCAowrBDKSIpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpgYGAKClNob3duIGhlcmUgaXMgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGZlY3VuZGl0eSBhbmQgc2l6ZSwgc2hvd2luZyB0aGUgY2xhc3NpYyBwYXR0ZXJuIG9mIGluY3JlYXNpbmcgZWdnIHByb2R1Y3Rpb24gd2l0aCBpbmNyZWFzaW5nIHNpemUuIAoKYGBge3IgZmVjdW5kaXR5LXNpemUsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD03fQpjdG1heF9yZXNpZHMgJT4lICAKICBkcm9wX25hKGZlY3VuZGl0eSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHNpemUsIHkgPSBmZWN1bmRpdHksIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgbGluZXdpZHRoID0gMikgKyAKICBnZW9tX3BvaW50KHNpemUgPSAyLCBhbHBoYSA9IDAuNSkgKyAKICBsYWJzKHggPSAiUHJvc29tZSBsZW5ndGggKG1tKSIsIAogICAgICAgeSA9ICJGZWN1bmRpdHkgKCMgRWdncykiLAogICAgICAgY29sb3VyID0gIlNwZWNpZXMiKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCmBgYAoKSW5kaXZpZHVhbHMgbWF5IGFsc28gYWxsb2NhdGUgZW5lcmd5IHRvIGRpZmZlcmVudCBmaXRuZXNzIHJlbGF0ZWQgdHJhaXRzLCBwcmlvcml0aXppbmcgcmVwcm9kdWN0aXZlIG91dHB1dCBvdmVyIGVudmlyb25tZW50YWwgdG9sZXJhbmNlLCBmb3IgZXhhbXBsZS4gU2hvd24gYmVsb3cgaXMgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIENUbWF4IHJlc2lkdWFscyAoYWdhaW4sIGNvbnRyb2xsaW5nIGZvciB0aGUgZWZmZWN0cyBvZiBjb2xsZWN0aW9uIHRlbXBlcmF0dXJlKSBhZ2FpbnN0IGZlY3VuZGl0eS4gV2UgY2FuIHNlZSBjbGVhcmx5IHRoYXQgaW5kaXZpZHVhbHMgd2l0aCBpbmNyZWFzZWQgZmVjdW5kaXR5IGFyZSBub3QgZGVjcmVhc2luZyB0aGVybWFsIGxpbWl0cywgc3VnZ2VzdGluZyB0aGF0IHRoZXJlIGlzIG5vIGVuZXJnZXRpYyB0cmFkZS1vZmYgYmV0d2VlbiB0aGVzZSB0cmFpdHMuIAoKYGBge3IsIGN0bWF4LWZlY3VuZGl0eSwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTd9CmN0bWF4X3Jlc2lkcyAlPiUgIAogIGRyb3BfbmEoZmVjdW5kaXR5KSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gcmVzaWRzLCB5ID0gZmVjdW5kaXR5LCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYsIGxpbmV3aWR0aCA9IDIpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMiwgYWxwaGEgPSAwLjUpICsgCiAgbGFicyh4ID0gIkNUbWF4IFJlc2lkdWFscyIsIAogICAgICAgeSA9ICJGZWN1bmRpdHkgKCMgRWdncykiKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpmaXRuZXNzLm1vZGVsID0gbG0oZGF0YSA9IGN0bWF4X3Jlc2lkcywgCiAgICAgICAgICAgICAgICAgICBmZWN1bmRpdHkgfiByZXNpZHMgKiBzcF9uYW1lKQoKY2FyOjpBbm92YShmaXRuZXNzLm1vZGVsKQoKZW1tZWFuczo6ZW10cmVuZHMoZml0bmVzcy5tb2RlbCwgIHZhciA9ICJyZXNpZHMiLCJzcF9uYW1lIikKYGBgCgojIyBPdGhlciBwYXR0ZXJucyBpbiB2YXJpYXRpb24gCgoqTGVwdG9kaWFwdG9tdXMgc2ljaWxpcyogaXMgdGhlIG1vc3QgYWJ1bmRhbnQgc3BlY2llcyBkdXJpbmcgdGhlIHdpbnRlci4gVGhlcmUgd2FzIGEgbGFyZ2Ugc2hpZnQgaW4gdGhlIHNpemUgb2YgbWF0dXJlIGZlbWFsZXMgdG93YXJkcyB0aGUgZW5kIG9mIERlY2VtYmVyLiBUaGVzZSBsYXJnZSBhbmQgc21hbGwgaW5kaXZpZHVhbHMgYXJlIHRoZSBzYW1lIHNwZWNpZXMgKGNvbmZpcm1lZCB2aWEgQ09JIHNlcXVlbmNpbmcpLCBzdWdnZXN0aW5nIHRoaXMgc2hpZnQgbWF5IHJlZmxlY3QgYSB0cmFuc2l0aW9uIGZyb20gb25lIGdlbmVyYXRpb24gdG8gYW5vdGhlciBhbmQgdGhhdCwgdW5saWtlIGluIG1hbnkgb3RoZXIgbGFrZXMsIHRoZXJlIGFyZSB0d28gZ2VuZXJhdGlvbnMgb2YgKkwuIHNpY2lsaXMqIHBlciB5ZWFyIGluIExha2UgQ2hhbXBsYWluLiBUaGlzIHNpemUgZGlmZmVyZW5jZSBtYXkgYmUgY2F1c2VkIGJ5IGRpZmZlcmVuY2VzIGluIHRoZSBkZXZlbG9wbWVudGFsIGVudmlyb25tZW50cy4gRm9yIGV4YW1wbGUsIGluZGl2aWR1YWxzIGRldmVsb3BpbmcgaW4gSmFudWFyeSBncm93IHVwIGF0IHZlcnkgbG93IHRlbXBlcmF0dXJlcywgYW5kIHRoZXJlZm9yZSBtYXkgcmVhY2ggbGFyZ2VyIHNpemVzLiBUaGVzZSBpbmRpdmlkdWFscyBvdmVyc3VtbWVyIGluIGRlZXAgd2F0ZXJzLCB0aGVuIHJlLWVtZXJnZSBpbiBPY3RvYmVyIGFuZCBwcm9kdWNlIGEgbmV3IGdlbmVyYXRpb24uIFdhdGVyIHRlbXBlcmF0dXJlcyBhcmUgc3RpbGwgZmFpcmx5IGhpZ2ggdGhyb3VnaCBOb3ZlbWJlciwgd2hpY2ggcmVzdWx0cyBpbiBhIGdlbmVyYXRpb24gb2Ygc21hbGxlciBpbmRpdmlkdWFscywgd2hpY2ggbWF0dXJlIGluIHRpbWUgdG8gcHJvZHVjZSBhIG5ldyBnZW5lcmF0aW9uIGluIEphbnVhcnkuIAoKU2hvd24gYmVsb3cgaXMgdGhlIGRpc3RyaWJ1dGlvbiBvZiBwYWlyd2lzZSBkaXN0YW5jZXMgYmV0d2VlbiBDT0kgc2VxdWVuY2VzIG9mIGxhcmdlIGFuZCBzbWFsbCBtb3JwaHMuIERpc3RhbmNlcyBpbiBib3RoIHdpdGhpbi0gYW5kIGFjcm9zcy1tb3JwaCBjb21wYXJpc29ucyBhcmUgc21hbGwuIAoKYGBge3J9CmluZF9kaXN0ID0gYXBlOjpkaXN0LmRuYShzaWNfZG5hYmluLCBtb2RlbCA9ICJyYXciKSAlPiUgYXMubWF0cml4ICU+JSAKICBhc190aWJibGUoKSAlPiUKICBtdXRhdGUoImluZDEiID0gY29sbmFtZXMoLikpICU+JSAKICBwaXZvdF9sb25nZXIoLWluZDEsIG5hbWVzX3RvID0gImluZDIiLCB2YWx1ZXNfdG8gPSAiZGlzdCIpICU+JQogIG11dGF0ZShpbmQxID0gZmFjdG9yKGluZDEpLAogICAgICAgICBpbmQyID0gZmFjdG9yKGluZDIpKSAlPiUgCiAgZmlsdGVyKCEoaW5kMSA9PSAic29yZTEiIHwgaW5kMiA9PSAic29yZTEiKSkgJT4lIAogIG11dGF0ZSgKICAgIGluZDEgPSBjYXNlX3doZW4oCiAgICAgIGluZDEgPT0gIlMxIiB+ICJzbWFsbDEiLAogICAgICBpbmQxID09ICJTMyIgfiAic21hbGwzIiwKICAgICAgaW5kMSA9PSAibHNpYzMiIH4gInNtYWxsNCIsCiAgICAgIGluZDEgPT0gImxzaWM1IiB+ICJzbWFsbDYiLAogICAgICBpbmQxID09ICJsc2ljOSIgfiAic21hbGw4IiwKICAgICAgaW5kMSA9PSAibHNpYzEwIiB+ICJzbWFsbDkiLAogICAgICBpbmQxID09ICJsc2ljMTEiIH4gInNtYWxsMTAiLAogICAgICBpbmQxID09ICJMMSIgfiAibGFyZ2UxIiwKICAgICAgaW5kMSA9PSAiTDIiIH4gImxhcmdlMiIsCiAgICAgIGluZDEgPT0gIkwzIiB+ICJsYXJnZTMiLAogICAgICBpbmQxID09ICJsc2ljMSIgfiAibGFyZ2U0IiwKICAgICAgaW5kMSA9PSAibHNpYzIiIH4gImxhcmdlNSIsCiAgICAgIGluZDEgPT0gImxzaWM3IiB+ICJsYXJnZTYiLAogICAgICBpbmQxID09ICJsc2ljOCIgfiAibGFyZ2U3IiksCiAgICBpbmQyID0gY2FzZV93aGVuKAogICAgICBpbmQyID09ICJTMSIgfiAic21hbGwxIiwKICAgICAgaW5kMiA9PSAiUzMiIH4gInNtYWxsMyIsCiAgICAgIGluZDIgPT0gImxzaWMzIiB+ICJzbWFsbDQiLAogICAgICBpbmQyID09ICJsc2ljNSIgfiAic21hbGw2IiwKICAgICAgaW5kMiA9PSAibHNpYzkiIH4gInNtYWxsOCIsCiAgICAgIGluZDIgPT0gImxzaWMxMCIgfiAic21hbGw5IiwKICAgICAgaW5kMiA9PSAibHNpYzExIiB+ICJzbWFsbDEwIiwKICAgICAgaW5kMiA9PSAiTDEiIH4gImxhcmdlMSIsCiAgICAgIGluZDIgPT0gIkwyIiB+ICJsYXJnZTIiLAogICAgICBpbmQyID09ICJMMyIgfiAibGFyZ2UzIiwKICAgICAgaW5kMiA9PSAibHNpYzEiIH4gImxhcmdlNCIsCiAgICAgIGluZDIgPT0gImxzaWMyIiB+ICJsYXJnZTUiLAogICAgICBpbmQyID09ICJsc2ljNyIgfiAibGFyZ2U2IiwKICAgICAgaW5kMiA9PSAibHNpYzgiIH4gImxhcmdlNyIpLAogICAgJ2NvbXBhcmlzb24nID0gY2FzZV93aGVuKAogICAgICBzdHJfZGV0ZWN0KGluZDEsIHBhdHRlcm4gPSAibGFyZ2UiKSAmIHN0cl9kZXRlY3QoaW5kMiwgcGF0dGVybiA9ICJsYXJnZSIpIH4gIndpdGhpbiIsCiAgICAgIHN0cl9kZXRlY3QoaW5kMSwgcGF0dGVybiA9ICJzbWFsbCIpICYgc3RyX2RldGVjdChpbmQyLCBwYXR0ZXJuID0gInNtYWxsIikgfiAid2l0aGluIiwgCiAgICAgIHN0cl9kZXRlY3QoaW5kMSwgcGF0dGVybiA9ICJsYXJnZSIpICYgc3RyX2RldGVjdChpbmQyLCBwYXR0ZXJuID0gInNtYWxsIikgfiAiYWNyb3NzIiwKICAgICAgc3RyX2RldGVjdChpbmQxLCBwYXR0ZXJuID0gInNtYWxsIikgJiBzdHJfZGV0ZWN0KGluZDIsIHBhdHRlcm4gPSAibGFyZ2UiKSB+ICJhY3Jvc3MiCiAgICApKSAKCmdncGxvdChpbmRfZGlzdCwgYWVzKGRpc3QsIGZpbGwgPSBjb21wYXJpc29uKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC4wMDUpICsgCiAgbGFicyh4ID0gIkRpc3RhbmNlIikgKyAKICB0aGVtZV9tYXR0KCkKYGBgCgoKYGBge3J9CmZ1bGxfZGF0YSAlPiUgIAogIGZpbHRlcihzcF9uYW1lID09ICJMZXB0b2RpYXB0b211cyBzaWNpbGlzIikgJT4lIAogIGZpbHRlcihzZXggIT0gImp1dmVuaWxlIikgJT4lIAogIGdyb3VwX2J5KGNvbGxlY3Rpb25fZGF0ZSkgJT4lIAogIG11dGF0ZShzaXplX2NlbnRlciA9IHNjYWxlKHNpemUsIGNlbnRlciA9IFQsIHNjYWxlID0gRikpICU+JSAKICBnZ3Bsb3QoYWVzKHkgPSBjb2xsZWN0aW9uX2RhdGUsIHggPSBzaXplLCBmaWxsID0gY29sbGVjdGlvbl90ZW1wKSkgKyAKICBmYWNldF93cmFwKHNleH4uKSArIAogIGdlb21fZGVuc2l0eV9yaWRnZXMoYmFuZHdpZHRoID0gMC4wNCkgKyAKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLjg5KSArIAogIGxhYnMoeCA9ICJTaXplIChtbSkiLAogICAgICAgeSA9ICJEYXRlIiwgCiAgICAgICBmaWxsID0gIkNvbGwuIFRlbXAuICjCsEMpIikgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMikpCmBgYAoKYGBge3J9CmZ1bGxfZGF0YSAlPiUgIAogIGZpbHRlcihzcF9uYW1lID09ICJMZXB0b2RpYXB0b211cyBtaW51dHVzIikgJT4lIAogIGZpbHRlcihzZXggIT0gImp1dmVuaWxlIikgJT4lIAogIGdncGxvdChhZXMoeSA9IGNvbGxlY3Rpb25fZGF0ZSwgeCA9IHNpemUsIGZpbGwgPSBjb2xsZWN0aW9uX3RlbXApKSArIAogIGZhY2V0X3dyYXAoc2V4fi4pICsgCiAgZ2VvbV9kZW5zaXR5X3JpZGdlcyhiYW5kd2lkdGggPSAwLjA0KSArIAogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAuNjkpICsgCiAgbGFicyh4ID0gIlNpemUgKG1tKSIsCiAgICAgICB5ID0gIkRhdGUiLCAKICAgICAgIGZpbGwgPSAiQ29sbC4gVGVtcC4gKMKwQykiKSArIAogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygwLjUsMC45KSkgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMikpCmBgYAoKIyMgRGlzdHJpYnV0aW9uIExhZyBOb24tTGluZWFyIE1vZGVsIChETE5NIGFwcHJvYWNoKSAKYGBge3J9CmRsbm1fZGF0YSA9IGZ1bGxfZGF0YSAlPiUgIAogIGZpbHRlcihzZXggPT0gImZlbWFsZSIpICU+JSAKICBzZWxlY3QoY29sbGVjdGlvbl9kYXRlLCBkYXlzX2luX2xhYiwgY29sbGVjdGlvbl90ZW1wLCByZXBsaWNhdGUsIHNwX25hbWUsIHNpemUsIGZlY3VuZGl0eSwgY3RtYXgpICU+JSAKICBncm91cF9ieShjb2xsZWN0aW9uX2RhdGUsIGNvbGxlY3Rpb25fdGVtcCwgc3BfbmFtZSkgJT4lICAKICBzdW1tYXJpc2UobWVhbl9jdG1heCA9IG1lYW4oY3RtYXgsIG5hLnJtID0gVCksCiAgICAgICAgICAgIG1lYW5fc2l6ZSA9IG1lYW4oc2l6ZSwgbmEucm0gPSBUKSwKICAgICAgICAgICAgc2FtcGxlID0gbigpKQpgYGAKCmBgYHtyfQpob3VybHlfdGVtcHMgPSByYXdfdGVtcHMgJT4lICAKICBtdXRhdGUoaG91ciA9IGx1YnJpZGF0ZTo6aG91cihkYXRlVGltZSkpICU+JSAgCiAgZ3JvdXBfYnkoZGF0ZSwgaG91cikgJT4lICAKICBzdW1tYXJpc2UobWVhbl90ZW1wID0gbWVhbihkZWdDKSkgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgY29tcGxldGUoZGF0ZSwgbmVzdGluZyhob3VyKSkgJT4lICAKICBtdXRhdGUodGltZXN0ZXAgPSB5bWRfaG1zKAogICAgcGFzdGUobHVicmlkYXRlOjphc19kYXRlKGRhdGUpLCAKICAgICAgICAgIHBhc3RlMChob3VyLCAiOjAwOjAwIiksIHNlcCA9ICIgIikpLAogICAgb2JzZXJ2YXRpb24gPSByb3dfbnVtYmVyKCkpIAoKYGBgCgpgYGB7cn0KaWYocHJlZGljdF92dWxuID09IEYpewogIGtuaXRyOjprbml0X2V4aXQoKQp9CmBgYAoKCiMjIFByZWRpY3RpbmcgVnVsbmVyYWJpbGl0eSAKVXNpbmcgdGhlIG9ic2VydmVkIHRoZXJtYWwgbGltaXQgZGF0YSwgd2UgY2FuIHByb2R1Y2UgYSBoaW5kY2FzdCBvZiB0aGVybWFsIHN0cmVzcyBmb3IgTGFrZSBDaGFtcGxhaW4gY29wZXBvZHMuIEZvciB0aGVzZSBpbml0aWFsIGFzc2F5cywgd2Ugd2lsbCBkZWZpbmUgdGhlcm1hbCBzdHJlc3MgYXMgYW55IHRpbWUgd2hlbiBtYXhpbXVtIGRhaWx5IHdhdGVyIHRlbXBlcmF0dXJlIGlzIHdpdGhpbiAywrBDIG9mIGNvcGVwb2QgQ1RtYXggb3IgaGlnaGVyLiBXZSB3aWxsIHVzZSB0aHJlZSBkaWZmZXJlbnQgc2NlbmFyaW9zOiAxKSB0aGUgYXZlcmFnZSBDVG1heCBmb3IgZWFjaCBzcGVjaWVzLCAyKSBDVG1heCBwcmVkaWN0ZWQgdXNpbmcgY29sbGVjdGlvbiB0ZW1wZXJhdHVyZXMsIGFuZCAzKSBmb3Igc3BlY2llcyB0aGF0IGhhdmUgc3VmZmljaWVudCBkYXRhLCBDVG1heCBwcmVkaWN0ZWQgdXNpbmcgd2hpY2hldmVyIGVudmlyb25tZW50YWwgZmFjdG9yIGlzIHRoZSBzdHJvbmdlc3QgY2FuZGlkYXRlIGZvciBkcml2aW5nIGFjY2xpbWF0aW9uLiBJbiBhbGwgY2FzZXMsIGRhdGEgaXMgZmlsdGVyZWQgdG8ganVzdCB0aGVybWFsIGxpbWl0cyBvZiBhZHVsdCBmZW1hbGVzLiAKCiMjIyBTY2VuYXJpbyAxCmBgYHtyfQptZWFuX2N0bWF4ID0gZnVsbF9kYXRhICU+JSAKICBmaWx0ZXIoc2V4ID09ICJmZW1hbGUiKSAlPiUgIAogIGdyb3VwX2J5KHNwX25hbWUpICU+JSAKICBzdW1tYXJpemUoIm1lYW5fY3RtYXgiID0gbWVhbihjdG1heCkpICU+JSAKICBhcnJhbmdlKG1lYW5fY3RtYXgpCgprbml0cjo6a2FibGUobWVhbl9jdG1heCkKYGBgCgpgYGB7cn0KIyAjIENvbnN0cnVjdHMgdGhlIFVSTCBmb3IgdGhlIGZ1bGwgdGVtcGVyYXR1cmUgZGF0YSBzZXQ7IFJVTiBUSElTIE9OQ0UKIyBoaW5kX3VybCA9IGNvbnN0cnVjdE5XSVNVUkwoc2l0ZU51bWJlcnMgPSBzaXRlTnVtYmVyLCBwYXJhbWV0ZXJDZCA9IHBhcmFtZXRlckNkLCBzZXJ2aWNlID0gInV2IikKIyAKIyBoaW5kX3RlbXBfZGF0YSA9IGltcG9ydFdhdGVyTUwxKGhpbmRfdXJsLCBhc0RhdGVUaW1lID0gVCkgJT4lCiMgICBtdXRhdGUoImRhdGUiID0gYXMuRGF0ZShkYXRlVGltZSkpICU+JQojICAgc2VsZWN0KGRhdGUsICJ0ZW1wIiA9IFhfMDAwMTBfMDAwMDApCiMgCiMgd3JpdGUudGFibGUoeCA9IGhpbmRfdGVtcF9kYXRhLCBmaWxlID0gImhpbmRjYXN0X3RlbXBzLmNzdiIsIHJvdy5uYW1lcyA9IEYsIHNlcCA9ICIsIikKYGBgCgpgYGB7cn0KIyBnZ3Bsb3QoaGluZF90ZW1wX2RhdGEsIGFlcyh4ID0gZGF0ZSwgeSA9IHRlbXApKSArIAojICAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDAuMSkgKyAKIyAgIGxhYnMoeCA9ICJEYXRlIiwgCiMgICAgICAgIHkgPSAiV2F0ZXIgVGVtcGVyYXR1cmUgKMKwQykiKSArCiMgICB0aGVtZV9tYXR0KCkKYGBgCgpJbiB0aGUgc2ltcGxlc3Qgc2NlbmFyaW8sIHNwZWNpZXMgdGhlcm1hbCBsaW1pdHMgYXJlIHN0YXRpYyB0aHJvdWdoIHRpbWUsIHJlcHJlc2VudGVkIGJ5IHRoZSBhdmVyYWdlIENUbWF4IG9mIGFkdWx0IGZlbWFsZSBjb3BlcG9kcy4gSW4gdGhpcyBzY2VuYXJpbywgb25seSB0aHJlZSBvZiB0aGUgc2V2ZW4gb2JzZXJ2ZWQgc3BlY2llcyBhcmUgZXhwb3NlZCB0byB0aGVybWFsIHN0cmVzcyAodGVtcGVyYXR1cmVzIHdpdGhpbiA1wrBDIG9mIENUbWF4KS4gVGVtcGVyYXR1cmVzIGFwcHJvYWNoZWQgdGhlIHRoZXJtYWwgbGltaXQgb2YgKkxlcHRvZGlhcHRvbXVzIHNpY2lsaXMqIG9uIGEgaGFuZGZ1bCBvZiBkYXlzLiBCeSBjb250cmFzdCwgKlNlbmVjZWxsYSBjYWxhbm9pZGVzKiBhbmQgKkxpbW5vY2FsYW51cyBtYWNydXJ1cyogd2VyZSBib3RoIGV4cG9zZWQgdG8gc3Vic3RhbnRpYWwgdGhlcm1hbCBzdHJlc3MgdGhyb3VnaG91dCBhIGxhcmdlIHBvcnRpb24gb2YgdGhlIHllYXIsIGxpa2VseSBleHBsYWluaW5nIHdoeSB0aGVzZSBzcGVjaWVzIGFyZSBhYnNlbnQgZnJvbSB0aGUgY29tbXVuaXR5IGZvciB0aGUgc3VtbWVyIGFuZCBmYWxsIHBlcmlvZHMuIAoKYGBge3IgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTV9CmhpbmQxX2RhdGEgPSBoaW5kX3RlbXBfZGF0YSAlPiUgCiAgZ3JvdXBfYnkoZGF0ZSkgJT4lIAogIHN1bW1hcml6ZSgiZGFpbHlfbWF4IiA9IG1heCh0ZW1wKSwKICAgICAgICAgICAgImRhaWx5X21lYW4iID0gbWVhbih0ZW1wKSwpICU+JSAKICBiaW5kX2NvbHMocGl2b3Rfd2lkZXIobWVhbl9jdG1heCwgbmFtZXNfZnJvbSA9IHNwX25hbWUsIHZhbHVlc19mcm9tID0gbWVhbl9jdG1heCkpICU+JSAgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKC1kYXRlLCAtZGFpbHlfbWF4LCAtZGFpbHlfbWVhbiksCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gInNwZWNpZXMiLCAKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gIm1lYW5fY3RtYXgiKSAlPiUgIAogIG11dGF0ZShsaW1fZGlmZiA9IG1lYW5fY3RtYXggLSBkYWlseV9tYXgpICU+JSAgCiAgbXV0YXRlKGRveSA9IHlkYXkoZGF0ZSksCiAgICAgICAgICJtZXRob2QiID0gIk5vX2FjY2xpbWF0aW9uIikKCmhpbmRfZGFpbHlfdGVtcF9kYXRhID0gaGluZF90ZW1wX2RhdGEgJT4lCiAgdW5ncm91cCgpICU+JSAKICBncm91cF9ieShkYXRlKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fdGVtcCA9IG1lYW4odGVtcCksCiAgICAgICAgICAgIG1lZF90ZW1wID0gbWVkaWFuKHRlbXApLAogICAgICAgICAgICB2YXJfdGVtcCA9IHZhcih0ZW1wKSwgCiAgICAgICAgICAgIG1pbl90ZW1wID0gbWluKHRlbXApLCAKICAgICAgICAgICAgbWF4X3RlbXAgPSBtYXgodGVtcCkpICU+JSAKICBtdXRhdGUoInJhbmdlX3RlbXAiID0gbWF4X3RlbXAgLSBtaW5fdGVtcCkKCiN0YWJsZShoaW5kMV9kYXRhJHNwZWNpZXMpCgpoaW5kMV9kYXRhICU+JSAKICBmaWx0ZXIobGltX2RpZmYgPD0gNSkgJT4lICAKICBnZ3Bsb3QoYWVzKHggPSBkb3ksIHkgPSBsaW1fZGlmZiwgY29sb3VyID0gc3BlY2llcykpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDUsIAogICAgICAgICAgICAgY29sb3VyID0gImdyZXkiKSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjUpICsKICBnZW9tX3Ntb290aChzZSA9IEYpICsgCiAgbGFicyh4ID0gIkRheSBvZiBZZWFyIiwgCiAgICAgICB5ID0gIlByZWRpY3RlZCBXYXJtaW5nIFRvbGVyYW5jZSBcbijCsEMgQWJvdmUgRGFpbHkgTWF4KSIpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKYGBgCgojIyMgU2NlbmFyaW8gMgpJbiB0aGUgc2Vjb25kIHNjZW5hcmlvLCB0aGVybWFsIGxpbWl0cyB2YXJ5IHdpdGhpbiBhbmQgYmV0d2VlbiBzcGVjaWVzLiBBIHNpbXBsZSBtb2RlbCBpcyB1c2VkIHRvIHByZWRpY3Qgc3BlY2llcyB0aGVybWFsIGxpbWl0cyBiYXNlZCBvbiBtZWFuIGRhaWx5IHRlbXBlcmF0dXJlIChDVG1heCBhcyBhIGZ1bmN0aW9uIG9mIHNwZWNpZXMgYW5kIGNvbGxlY3Rpb24gdGVtcGVyYXR1cmUsIGJ1dCB3aXRob3V0IHRoZSBpbnRlcmFjdGlvbiBiZXR3ZWVuIHRoZXNlIHR3byBmYWN0b3JzKS4gVGhlc2UgcHJlZGljdGVkIHRoZXJtYWwgbGltaXRzIGFyZSB0aGVuIGNvbXBhcmVkIGFnYWluc3QgdGhlIG1heGltdW0gZGFpbHkgdGVtcGVyYXR1cmUgdG8gZXN0aW1hdGUgdGhlcm1hbCBzdHJlc3MsIGFzIGluIFNjZW5hcmlvIDEuIEluY2x1ZGluZyB0aGlzIHNpbXBsZSBmb3JtIG9mIGFjY2xpbWF0aW9uIGluIHRoZSBtb2RlbCByZWR1Y2VkIHRoZSBkZWdyZWUgb2YgdGhlcm1hbCBzdHJlc3MgZm9yIGVhY2ggc3BlY2llcywgZWxpbWluYXRpbmcgaXQgZW50aXJlbHkgZm9yICpMZXB0b2RpYXB0b211cyBzaWNpbGlzKi4gTm90ZSB0aGF0IHRoZSBtYWduaXR1ZGUgb2YgdGhlIHByZWRpY3RlZCBzdHJlc3MgaXMgIGxvdyBlbm91Z2ggdGhhdCByZW1vdmluZyB0aGUgNcKwQyBidWZmZXIgYXJvdW5kIHRoZSBwcmVkaWN0ZWQgdGhlcm1hbCBsaW1pdHMgd291bGQgYWN0dWFsbHkgbGltaXQgcHJlZGljdGVkIHRoZXJtYWwgc3RyZXNzIHRvIGp1c3QgYSBmZXcgZGF5cyBmb3IgKlNlbmVjZWxsYSBjYWxhbm9pZGVzKi4gCgpgYGB7ciBmaWcuaGVpZ2h0PTUsIGZpZy53aWR0aD0xMH0KaGluZGNhc3RfbW9kZWwxID0gbG0oZGF0YSA9IGZpbHRlcihmdWxsX2RhdGEsIHNleCA9PSAiZmVtYWxlIiksCiAgICAgICAgICAgICAgICAgICAgIGN0bWF4IH4gY29sbGVjdGlvbl90ZW1wICsgc3BfbmFtZSkKCmhpbmQyX2RhdGEgPSBoaW5kX3RlbXBfZGF0YSAlPiUgCiAgZ3JvdXBfYnkoZGF0ZSkgJT4lIAogIHN1bW1hcml6ZSgiY29sbGVjdGlvbl90ZW1wIiA9IG1lYW4odGVtcCksCiAgICAgICAgICAgICJkYWlseV9tYXgiID0gbWF4KHRlbXApKSAlPiUgCiAgYmluZF9jb2xzKAogICAgcGl2b3Rfd2lkZXIobWVhbl9jdG1heCwgCiAgICAgICAgICAgICAgICBuYW1lc19mcm9tID0gc3BfbmFtZSwgCiAgICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IG1lYW5fY3RtYXgpKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKC1kYXRlLCAtZGFpbHlfbWF4LCAtY29sbGVjdGlvbl90ZW1wKSwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAic3BfbmFtZSIsIAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAibWVhbl9jdG1heCIpICU+JSAKICBzZWxlY3QoLW1lYW5fY3RtYXgpICU+JSAKICBtdXRhdGUoInByZWRfY3RtYXgiID0gcHJlZGljdC5sbSAoaGluZGNhc3RfbW9kZWwxLCBuZXdkYXRhID0gLikpICU+JSAKICBzZWxlY3QoZGF0ZSwgImRhaWx5X21lYW4iID0gY29sbGVjdGlvbl90ZW1wLCBkYWlseV9tYXgsICJzcGVjaWVzIiA9IHNwX25hbWUsIHByZWRfY3RtYXgpICU+JSAKICBtdXRhdGUobGltX2RpZmYgPSBwcmVkX2N0bWF4IC0gZGFpbHlfbWF4KSAlPiUgCiAgI2ZpbHRlcihsaW1fZGlmZiA8PSAwKSAlPiUgIAogIG11dGF0ZShkb3kgPSB5ZGF5KGRhdGUpLAogICAgICAgICAibWV0aG9kIiA9ICJDb25zdGFudF9hY2NsaW1hdGlvbiIpCgojIGdncGxvdChoaW5kMl9kYXRhLCBhZXMoeCA9IGRhaWx5X21lYW4sIHkgPSBwcmVkX2N0bWF4LCBjb2xvdXIgPSBzcGVjaWVzKSkgKwojICAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikgCgojIHRhYmxlKGhpbmQyX2RhdGEkc3BlY2llcykKaGluZDJfZGF0YSAlPiUgIAogIGZpbHRlcihsaW1fZGlmZiA8PSA1KSAlPiUgIAogIGdncGxvdChhZXMoeCA9IGRveSwgeSA9IGxpbV9kaWZmLCBjb2xvdXIgPSBzcGVjaWVzKSkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDApICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gNSwgCiAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleSIpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNSkgKwogIGdlb21fc21vb3RoKCkgKyAKICBsYWJzKHggPSAiRGF5IG9mIFllYXIiLCAKICAgICAgIHkgPSAiUHJlZGljdGVkIFdhcm1pbmcgVG9sZXJhbmNlIFxuKMKwQyBBYm92ZSBEYWlseSBNYXgpIikgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQpgYGAKCiMjIyBTY2VuYXJpbyAzClRoZSBmaW5hbCBzY2VuYXJpbyBhbGxvd3MgdGhlIGVudmlyb25tZW50YWwgdmFyaWFibGUgdXNlZCB0byBwcmVkaWN0IENUbWF4IHRvIHZhcnkgYmV0d2VlbiBzcGVjaWVzLiBGb3Igc3BlY2llcyBvYnNlcnZlZCBpbiBmZXdlciB0aGFuIDUgY29sbGVjdGlvbnMsIHdlIHVzZSB0aGUgc2FtZSBhcHByb2FjaCBhcyBpbiBTY2VuYXJpbyAyLiBGb3Igc3BlY2llcyBvYnNlcnZlZCBpbiBtb3JlIHRoYW4gNSBjb2xsZWN0aW9ucywgaG93ZXZlciwgdGhlIGZhY3RvciB3aXRoIHRoZSBzdHJvbmdlc3QgY29ycmVsYXRpb24gd2l0aCBDVG1heCBpcyB1c2VkIHRvIHByZWRpY3QgdGhlcm1hbCBsaW1pdHMuIFRoZXNlIGZhY3RvcnMgYXJlIGluY2x1ZGVkIGJlbG93LgoKYGBge3J9CmhpbmRfcHJlZHMgPSBjb3JyX3ZhbHMgJT4lICAKICBmaWx0ZXIoc2lnID09ICJTaWcuIikgJT4lIAogIGRyb3BfbmEoY29ycmVsYXRpb24pICU+JSAKICBncm91cF9ieShzcF9uYW1lKSAlPiUKICBhcnJhbmdlKGRlc2MoY29ycmVsYXRpb24pKSAlPiUgCiAgc2xpY2VfaGVhZChuID0gMSkgJT4lIAogIHNlbGVjdCgiU3BlY2llcyIgPSBzcF9uYW1lLCAiUHJlZGljdG9yIiA9IHBhcmFtZXRlciwgIkR1cmF0aW9uIiA9IGR1cmF0aW9uLCAiQ29ycmVsYXRpb24iID0gY29ycmVsYXRpb24sICJQLVZhbHVlIiA9IHAudmFsdWUpCgprbml0cjo6a2FibGUoaGluZF9wcmVkcywgYWxpZ24gPSAiYyIpCmBgYAoKYGBge3J9CmhpbmQzX2RhdGEgPSBoaW5kMl9kYXRhICU+JSAjIENvbnRhaW5zIGRhdGEgZm9yIHNwZWNpZXMgdGhhdCB3b24ndCBjaGFuZ2UgZnJvbSBzY2VuYXJpbyAyCiAgZmlsdGVyKCEoc3BlY2llcyAlaW4lIGNvcnJfdmFscyRzcF9uYW1lKSkKCnByZWRzX3RvX3B1bGwgPSBoaW5kX3ByZWRzICU+JSAgCiAgc2VsZWN0KFNwZWNpZXMsIFByZWRpY3RvciwgRHVyYXRpb24pIAoKZm9yKGkgaW4gMTpsZW5ndGgocHJlZHNfdG9fcHVsbCRTcGVjaWVzKSl7CiAgCiAgaWYocHJlZHNfdG9fcHVsbCREdXJhdGlvbltpXSA9PSAicHJpb3IiKXsgI1RoZSBwcmlvciBkYXkgdGVtcGVyYXR1cmUgbWV0cmljcyBzaG91bGQgYmUgdXNlZAogICAgZHVyYXRpb24gPSBOQQogICAgCiAgICBwcmVkaWN0b3JzID0gaGluZF9kYWlseV90ZW1wX2RhdGEgJT4lIAogICAgICBtdXRhdGUoZGF0ZSA9IGRhdGUgKyAxKSAKICAgIAogICAgcGFyYW1ldGVyID0gcHJlZHNfdG9fcHVsbCRQcmVkaWN0b3JbaV0KICAgIAogICAgbW9kZWxfZGF0YSA9IGZ1bGxfZGF0YSAlPiUKICAgICAgZmlsdGVyKHNwX25hbWUgJWluJSBwcmVkc190b19wdWxsJFNwZWNpZXNbaV0pICU+JSAKICAgICAgZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lIAogICAgICBtdXRhdGUoY29sbGVjdGlvbl9kYXRlID0gYXNfZGF0ZShjb2xsZWN0aW9uX2RhdGUpKSAlPiUgCiAgICAgIGlubmVyX2pvaW4ocHJlZGljdG9ycywgam9pbl9ieShjb2xsZWN0aW9uX2RhdGUgPT0gZGF0ZSkpICU+JSAgCiAgICAgIHNlbGVjdChjdG1heCwgY29udGFpbnMocGFyYW1ldGVyKSkKICAgIAogICAgaWYoZGltKG1vZGVsX2RhdGEpWzJdID09IDIpewogICAgICBoaW5kLm1vZGVsID0gbG0oZGF0YSA9IG1vZGVsX2RhdGEsIAogICAgICAgICAgICAgICAgICAgICAgY3RtYXggfiAuKQogICAgICAKICAgICAgc3BfZGF0YSA9IHByZWRpY3RvcnMgJT4lIAogICAgICAgIHNlbGVjdChkYXRlLCBjb250YWlucyhwYXJhbWV0ZXIpKSAlPiUgCiAgICAgICAgbXV0YXRlKHByZWRfY3RtYXggPSBwcmVkaWN0KGhpbmQubW9kZWwsIG5ld2RhdGEgPSAuKSkgJT4lICAKICAgICAgICBzZWxlY3QoZGF0ZSwgcHJlZF9jdG1heCkgJT4lIAogICAgICAgIGlubmVyX2pvaW4oaGluZF9kYWlseV90ZW1wX2RhdGEsIGJ5ID0gYygiZGF0ZSIpKSAlPiUgCiAgICAgICAgbXV0YXRlKCJzcGVjaWVzIiA9IHByZWRzX3RvX3B1bGwkU3BlY2llc1tpXSwKICAgICAgICAgICAgICAgImRveSIgPSB5ZGF5KGRhdGUpLAogICAgICAgICAgICAgICBsaW1fZGlmZiA9IHByZWRfY3RtYXggLSBtYXhfdGVtcCkgJT4lIAogICAgICAgIHNlbGVjdChkYXRlLCBkYWlseV9tZWFuID0gbWVhbl90ZW1wLCBkYWlseV9tYXggPSBtYXhfdGVtcCwgc3BlY2llcywgcHJlZF9jdG1heCwgbGltX2RpZmYsIGRveSkKICAgICAgCiAgICAgIGhpbmQzX2RhdGEgPSBiaW5kX3Jvd3MoaGluZDNfZGF0YSwgc3BfZGF0YSkKICAgIH1lbHNlewogICAgICBwcmludCgiVG9vIG1hbnkgY29sdW1ucyBzZWxlY3RlZCIpCiAgICB9CiAgICAKICAgIAogIH1lbHNlewogICAgZHVyYXRpb24gPSBhcy5udW1lcmljKHByZWRzX3RvX3B1bGwkRHVyYXRpb25baV0pCiAgfQogIAogIGlmKHByZWRzX3RvX3B1bGwkRHVyYXRpb25baV0gIT0gInByaW9yIiAmIGlzLm5hKGR1cmF0aW9uKSl7ICNEYWlseSB0ZW1wZXJhdHVyZXMgc2hvdWxkIGJlIHVzZWQsIGFzIGluIFNjZW5hcmlvIDIKICAgIHNwX2RhdGEgPSBoaW5kMl9kYXRhICU+JSAKICAgICAgZmlsdGVyKHNwZWNpZXMgPT0gcHJlZHNfdG9fcHVsbCRTcGVjaWVzW2ldKQogICAgCiAgICBoaW5kM19kYXRhID0gYmluZF9yb3dzKGhpbmQzX2RhdGEsIHNwX2RhdGEpCiAgfQogIAogIGlmKGlzLm51bWVyaWMoZHVyYXRpb24pKXsKICAgICNOZWl0aGVyIHRoZSBwcmlvciBkYXkgbm9yIGRheSBvZiBtZXRyaWNzIHNob3VsZCBiZSB1c2VkOyB1c2UgZHVyYXRpb24gYXMgbl9kYXlzCiAgICAKICAgIHByZWRpY3RvcnMgPSBnZXRfcHJlZGljdG9ycyhkYWlseV92YWx1ZXMgPSBoaW5kX2RhaWx5X3RlbXBfZGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmF3X3RlbXAgPSBoaW5kX3RlbXBfZGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbl9kYXlzID0gZHVyYXRpb24pCiAgICAKICAgIHBhcmFtZXRlciA9IHByZWRzX3RvX3B1bGwkUHJlZGljdG9yW2ldCiAgICAKICAgIG1vZGVsX2RhdGEgPSBmdWxsX2RhdGEgJT4lCiAgICAgIGZpbHRlcihzcF9uYW1lICVpbiUgcHJlZHNfdG9fcHVsbCRTcGVjaWVzW2ldKSAlPiUgCiAgICAgIGZpbHRlcihzZXggPT0gImZlbWFsZSIpICU+JSAKICAgICAgbXV0YXRlKGNvbGxlY3Rpb25fZGF0ZSA9IGFzX2RhdGUoY29sbGVjdGlvbl9kYXRlKSkgJT4lIAogICAgICBpbm5lcl9qb2luKHByZWRpY3RvcnMsIGpvaW5fYnkoY29sbGVjdGlvbl9kYXRlID09IGRhdGUpKSAlPiUgIAogICAgICBzZWxlY3QoY3RtYXgsIGNvbnRhaW5zKHBhc3RlKCJkYXlfIiwgcGFyYW1ldGVyLCBzZXAgPSAiIikpKQogICAgCiAgICBpZihkaW0obW9kZWxfZGF0YSlbMl0gPT0gMil7CiAgICAgIGhpbmQubW9kZWwgPSBsbShkYXRhID0gbW9kZWxfZGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICBjdG1heCB+IC4pCiAgICAgIAogICAgICBzcF9kYXRhID0gcHJlZGljdG9ycyAlPiUgCiAgICAgICAgc2VsZWN0KGRhdGUsIGNvbnRhaW5zKHBhcmFtZXRlcikpICU+JSAKICAgICAgICBtdXRhdGUocHJlZF9jdG1heCA9IHByZWRpY3QoaGluZC5tb2RlbCwgbmV3ZGF0YSA9IC4pKSAlPiUgIAogICAgICAgIHNlbGVjdChkYXRlLCBwcmVkX2N0bWF4KSAlPiUgCiAgICAgICAgaW5uZXJfam9pbihoaW5kX2RhaWx5X3RlbXBfZGF0YSwgYnkgPSBjKCJkYXRlIikpICU+JSAKICAgICAgICBtdXRhdGUoInNwZWNpZXMiID0gcHJlZHNfdG9fcHVsbCRTcGVjaWVzW2ldLAogICAgICAgICAgICAgICAiZG95IiA9IHlkYXkoZGF0ZSksCiAgICAgICAgICAgICAgIGxpbV9kaWZmID0gcHJlZF9jdG1heCAtIG1heF90ZW1wKSAlPiUgCiAgICAgICAgc2VsZWN0KGRhdGUsIGRhaWx5X21lYW4gPSBtZWFuX3RlbXAsIGRhaWx5X21heCA9IG1heF90ZW1wLCBzcGVjaWVzLCBwcmVkX2N0bWF4LCBsaW1fZGlmZiwgZG95KQogICAgICAKICAgICAgaGluZDNfZGF0YSA9IGJpbmRfcm93cyhoaW5kM19kYXRhLCBzcF9kYXRhKQogICAgICAKICAgIH1lbHNlewogICAgICBwcmludCgiVG9vIG1hbnkgY29sdW1ucyBzZWxlY3RlZCIpCiAgICB9CiAgICAKICB9Cn0KCmhpbmQzX2RhdGEgPSBoaW5kM19kYXRhICU+JSAKICBtdXRhdGUoIm1ldGhvZCIgPSAiVmFyaWFibGVfYWNjbGltYXRpb24iKQpgYGAKClRoaXMgdGhpcmQgYXBwcm9hY2ggZGlkIG5vdCBhZmZlY3QgdGhlIHByZWRpY3RlZCBwYXR0ZXJucyBpbiAqTGltbm9jYWxhbnVzKiBvciAqU2VuZWNlbGxhKiAobmVpdGhlciBzcGVjaWVzIGhhcyBiZWVuIG9ic2VydmVkIGluIGVub3VnaCBjb2xsZWN0aW9ucyB0byBlc3RpbWF0ZSB0aGUgZWZmZWN0cyBvZiBkaWZmZXJlbnQgZW52aXJvbm1lbnRhbCBmYWN0b3JzKS4gQ2hhbmdpbmcgdGhlIGFjY2xpbWF0aW9uIGFwcHJvYWNoIGRpZCBhZmZlY3QgcGF0dGVybnMgaW4gdGhlcm1hbCBsaW1pdHMgaW4gdGhlIG90aGVyIHNwZWNpZXMgdGhvdWdoLiBUaGUgZmlndXJlIGJlbG93IHNob3dzIGhvdyBwcmVkaWN0ZWQgd2FybWluZyB0b2xlcmFuY2UgdmFyaWVzIG92ZXIgdGhlIHllYXIgaW4gdGhlIHNldmVuIHNwZWNpZXMsIGJhc2VkIG9uIHRoZSB0aHJlZSBkaWZmZXJlbnQgcHJlZGljdGlvbiBtZXRob2RzLiBJbiBnZW5lcmFsLCBjb25zdGFudCB0aGVybWFsIGxpbWl0cyAodGhlICdubyBhY2NsaW1hdGlvbicgbWV0aG9kKSByZXN1bHRlZCBpbiBsYXJnZXIgd2FybWluZyB0b2xlcmFuY2UgZHVyaW5nIHRoZSB3aW50ZXIgYW5kIGxvd2VyIHdhcm1pbmcgdG9sZXJhbmNlIGR1cmluZyB0aGUgc3VtbWVyLCBhbHRob3VnaCB0aGlzIGVmZmVjdCB3YXMgc21hbGwgaW4gbW9zdCBzcGVjaWVzLiAgICAgCgpgYGB7ciBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9MTB9CnN5bnRoZXNpcyA9IGJpbmRfcm93cygKICBzZWxlY3QoaGluZDFfZGF0YSwgZGF0ZSwgZG95LCBkYWlseV9tZWFuLCBkYWlseV9tYXgsIHNwZWNpZXMsICJwcmVkX2N0bWF4IiA9IG1lYW5fY3RtYXgsIGxpbV9kaWZmLCBtZXRob2QpLAogIHNlbGVjdChoaW5kMl9kYXRhLCBkYXRlLCBkb3ksIGRhaWx5X21lYW4sIGRhaWx5X21heCwgIHNwZWNpZXMsIHByZWRfY3RtYXgsIGxpbV9kaWZmLCBtZXRob2QpLAogIHNlbGVjdChoaW5kM19kYXRhLCBkYXRlLCBkb3ksIGRhaWx5X21lYW4sIGRhaWx5X21heCwgIHNwZWNpZXMsIHByZWRfY3RtYXgsIGxpbV9kaWZmLCBtZXRob2QpKSAlPiUgCiAgbXV0YXRlKG1ldGhvZCA9IGZjdF9yZWxldmVsKG1ldGhvZCwgIk5vX2FjY2xpbWF0aW9uIiwgIkNvbnN0YW50X2FjY2xpbWF0aW9uIiwgIlZhcmlhYmxlX2FjY2xpbWF0aW9uIikpCgpjbGltYXRvbG9neSA9IHN5bnRoZXNpcyAlPiUgCiAgZ3JvdXBfYnkoc3BlY2llcywgZG95LCBtZXRob2QpICU+JSAgCiAgc3VtbWFyaXNlKCJtZWFuX2RpZmYiID0gbWVhbihsaW1fZGlmZiksCiAgICAgICAgICAgICJtaW5fZGlmZiIgPSBtaW4obGltX2RpZmYpLAogICAgICAgICAgICAibWF4X2RpZmYiID0gbWF4KGxpbV9kaWZmKSkgJT4lIAogIG11dGF0ZShtZXRob2QgPSBmY3RfcmVsZXZlbChtZXRob2QsICJOb19hY2NsaW1hdGlvbiIsICJDb25zdGFudF9hY2NsaW1hdGlvbiIsICJWYXJpYWJsZV9hY2NsaW1hdGlvbiIpKQoKYWNjX2VmZmVjdHMgPSBzeW50aGVzaXMgJT4lIAogIHBpdm90X3dpZGVyKGlkX2NvbHMgPSBjKGRhdGUsIHNwZWNpZXMsIGRveSksIAogICAgICAgICAgICAgIG5hbWVzX2Zyb20gPSBtZXRob2QsIAogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gbGltX2RpZmYpICU+JSAgCiAgbXV0YXRlKCJjb25zdF9hY2NfZWZmZWN0IiA9IENvbnN0YW50X2FjY2xpbWF0aW9uIC0gTm9fYWNjbGltYXRpb24sCiAgICAgICAgICJ2YXJfYWNjX2VmZmVjdCIgPSBWYXJpYWJsZV9hY2NsaW1hdGlvbiAtIE5vX2FjY2xpbWF0aW9uKQoKZ2dwbG90KHN5bnRoZXNpcywgYWVzKHggPSBkb3ksIHkgPSBsaW1fZGlmZiwgY29sb3VyID0gbWV0aG9kKSkgKyAKICBmYWNldF93cmFwKHNwZWNpZXN+LikgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDUsIGNvbG91ciA9ICJncmV5IikgKyAKICBnZW9tX3BvaW50KGFscGhhID0gMC4xKSArIAogIGxhYnMoeCA9ICJEYXkgb2YgWWVhciIsIAogICAgICAgeSA9ICJQcmVkaWN0ZWQgV2FybWluZyBUb2xlcmFuY2UgKMKwQyBBYm92ZSBEYWlseSBNYXgpIikgKyAKICBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAxKSkpICsgCiAgdGhlbWVfbWF0dF9mYWNldHMoYmFzZV9zaXplID0gMTgpICsgCiAgdGhlbWUoc3RyaXAudGV4dC54LnRvcCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKQpgYGAKCmBgYHtyLCBpbmNsdWRlID0gRn0KeWVhcmx5X3N1bW1hcnkgPSBzeW50aGVzaXMgJT4lICAKICBtdXRhdGUoInllYXIiID0geWVhcihkYXRlKSkgJT4lIAogIGdyb3VwX2J5KHNwZWNpZXMsIHllYXIsIG1ldGhvZCkgJT4lIAogIHN1bW1hcmlzZSgibWluX3d0IiA9IG1pbihsaW1fZGlmZiksCiAgICAgICAgICAgICJtYXhfd3QiID0gbWF4KGxpbV9kaWZmKSkgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gYyhtaW5fd3QsIG1heF93dCksIAogICAgICAgICAgICAgICBuYW1lc190byA9ICJtZXRyaWMiLCAKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInd0IikKCmdncGxvdCh5ZWFybHlfc3VtbWFyeSwgYWVzKHggPSBtZXRob2QsIHkgPSB3dCwgY29sb3VyID0gbWV0cmljKSkgKyAKICBmYWNldF93cmFwKC5+c3BlY2llcykgKyAKICBnZW9tX3BvaW50KCkgKyAKICB0aGVtZV9tYXR0X2ZhY2V0cygpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMDAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpKQpgYGAKCg==